Тема: Как перезапустить тему после завершения?

У меня есть метод void DoWork(object input) Это займет примерно 5 секунд. Я прочитал это Thread лучше подходит чем ThreadPool для этих более длительных операций, но я столкнулся с проблемой.

Я нажимаю кнопку, которая вызывает threadRun.Start(input) который работает и завершает нормально. Я снова нажимаю кнопку и получаю следующее исключение:

Thread is running or terminated; it cannot restart.

Разве вы не можете "повторно использовать" тему? Должен ли я использовать ThreadPool? Почему Thread "лучше подходит для более длительных операций" по сравнению с ThreadPool? Если вы не можете повторно использовать поток, зачем вообще его использовать (т.е. какие преимущества он предлагает)?

6 ответов

Решение

Разве вы не можете "повторно использовать" тему?

Вы можете. Но вы должны закодировать поток, чтобы не завершать его, а вместо этого ждать дополнительной работы. Вот что делает пул потоков.

Должен ли я использовать ThreadPool?

Если вы хотите повторно использовать поток, да.

Почему Thread "лучше подходит для более длительных операций" по сравнению с ThreadPool?

Представьте себе пул потоков, который обслуживает большое количество быстрых операций. Вы не хотите иметь слишком много потоков, потому что компьютер может делать столько всего за раз. Каждая длинная операция, которую вы делаете пулом потоков, связывает поток из пула. Таким образом, в пуле либо должно быть много дополнительных потоков, либо может не хватать потоков. Ни то, ни другое не приводит к эффективному проектированию пула потоков.

Для более длительных операций издержки на создание и уничтожение потока очень малы по сравнению со стоимостью операции. Таким образом, обычный недостаток использования потока только для операции не применяется.

Если вы не можете повторно использовать поток, зачем вообще его использовать (т.е. какие преимущества он предлагает)?

Я предполагаю, что вы имеете в виду использование потока, выделенного для задания, которое затем завершается использованием пула потоков. Преимущество состоит в том, что таким образом количество потоков всегда будет равно количеству заданий. Это означает, что вам нужно создавать поток каждый раз, когда вы запускаете задание, и уничтожать поток каждый раз, когда вы его заканчиваете, но у вас никогда не бывает лишних потоков, и при этом вы никогда не заканчиваете потоки. (Это может быть хорошо с потоками, связанными с вводом / выводом, но может быть плохо, если большая часть потоков связана с процессором большую часть времени.)

Документация Thread.Start гласит:

Как только поток завершается, он не может быть перезапущен с другим вызовом Start.

Темы не могут быть использованы повторно. Я уже сталкивался с этой проблемой некоторое время назад, решением было создать новый Thread экземпляр, когда это необходимо.

По дизайну это выглядит так.

Я столкнулся с той же проблемой, и единственное решение, которое я мог найти, было воссоздать поток. В моем случае я не очень часто перезагружал нить, поэтому не стал смотреть дальше.

В результате поиска появился этот поток в social.msdn, где принятый ответ гласит:

остановленный или прерванный поток не может быть указан снова.

MSDN также повторяет это:

попытка перезапустить прерванный поток, вызвав Start для завершившегося потока, вызывает исключение ThreadStateException.

for(;;){} или же while(true){} полезные конструкции для "повторного использования" потока. Как правило, поток ожидает некоторый объект синхронизации в верхней части этих циклов. В вашем примере вы можете подождать событие или семафор и сообщить об этом с помощью своей кнопки OnClick() обработчик.

Как говорится в сообщении, вы не можете перезапустить поток. Вы можете просто создать новый поток для вашей следующей операции. Или вы можете рассмотреть проект, в котором фоновый поток продолжает работать до тех пор, пока он не завершит все ваши задачи, а не запускать новый поток для каждого из них.

Это просто в фоновом режиме. Похоже, вам нужно использовать ThreadPool, потому что перезапуск и повторное создание объектов Thread являются очень дорогими операциями. Если у вас есть долго выполняемое задание, которое может длиться дольше, чем ваш основной процесс, рассмотрите возможность использования службы Windows.

Другие вопросы по тегам