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

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

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

Thread is running or terminated; it cannot restart.

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

6 ответов


вы не можете "использовать" какой-нить?

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

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

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

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

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

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

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

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


нить.Старт документация говорит:

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

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


похоже, это дизайн.

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

поиск теперь появился эта тема на социальном.в MSDN где принятый ответ гласит:

остановленный или Прерванный поток нельзя указать снова.

на MSDN повторить и это тоже:

попытка перезапустить прерванный поток, вызвав Start в потоке, который завершил броски ThreadStateException.


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


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


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