У меня есть метод, который я вызываю внутри Thread.Here метод.
private System.Threading.Thread _thread;
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
private void DoWork()
{
while (!_shutdownEvent.WaitOne(0))
{
//Business logic
}
}
и теперь я начинаю тему.
_thread = new Thread(DoWork);
_thread.Start();
Теперь, согласно моему требованию, я хочу закрыть и перезапустить Thread. Для закрытия и перезапуска я пытаюсь использовать этот код.
_shutdownEvent.Set(); // trigger the thread to stop
_thread.Join();
но я думаю, что это неправильный способ закрыть Thread и снова перезапустить его.
Пожалуйста, помогите мне закрыть и перезапустить Thread в моем случае. Заранее спасибо..
Я бы посоветовал вам изучить Task Parallel Library
, которая обеспечивает мелкомасштабный контроль над ее исполнением и поддерживает механизм отмены через структуру CancellationToken
:
Вот пример:
var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token;
var task = Task.Factory.StartNew(() =>
{
// Were we already canceled?
ct.ThrowIfCancellationRequested();
bool moreToDo = true;
while (moreToDo)
{
// Poll on this property if you have to do
// other cleanup before throwing.
if (ct.IsCancellationRequested)
{
// Clean up here, then...
ct.ThrowIfCancellationRequested();
}
}
}, tokenSource.Token); // Pass same token to StartNew.
tokenSource.Cancel();
Что касается "перезапуска потока", вы не можете перезапустить Task
. Что вы можете сделать, так это увидеть, что оно было отменено (задача содержит свойство Status
которое будет Canceled
после отмены), и если да, выполните новую задачу.
Вы действительно должны стараться избегать управления потоками самостоятельно, и пусть CLR сделает это за вас. Создание потоков - это дорогостоящая деятельность, подверженная ошибкам, лучше всего оставить в покое.
FCL предоставляет типы, которые можно использовать для управления потоками. Взгляните на QueueUserWorkItem, который выполнит некоторый код, указанный в обратном вызове. Это хорошо работает в ситуациях, когда вы просто хотите сказать "Go do something", и вам все равно, когда/если он завершится, и он не имеет возвращаемого значения. Если вы хотите увидеть возвращаемое значение и знаете, когда что-то завершено, используйте задачи.
Я настоятельно рекомендую CLR через С# Jeffrey Richer. Он имеет отличный раздел для потоковой передачи и различные способы их использования в вашем.Net-коде.
То, как вы в настоящее время ожидаете завершения потока, выглядит прекрасным - нити умирают, когда заканчивается код, и Join
гарантирует, что он закончил.
Вы не можете перезапустить поток, но вам придется создать новый.
Я согласен с другими ответами, которые вы, возможно, захотите изучить в новых доступных технологиях, они позволяют использовать более читаемый код.
erm, попробуйте что-то современное.
private Task DoWork(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
// ... It would be nice if you could await something here.
}
return Task.FromResult(true);
}
то, просто сообщите CancellationToken
,
using (var cts = new CancellationTokenSource())
{
await Task.WhenAny(
DoWork(cts.Token),
SomeOtherWork())
cts.Cancel();
}