Как правильно закрыть тему в c #

1

У меня есть метод, который я вызываю внутри 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 в моем случае. Заранее спасибо..

  • 0
    Какую версию .NET Framework вы используете?
  • 0
    @YuvalItzchakov .Net4.0
Показать ещё 5 комментариев
Теги:
multithreading
task-parallel-library

4 ответа

3

Я бы посоветовал вам изучить 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 после отмены), и если да, выполните новую задачу.

3

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

FCL предоставляет типы, которые можно использовать для управления потоками. Взгляните на QueueUserWorkItem, который выполнит некоторый код, указанный в обратном вызове. Это хорошо работает в ситуациях, когда вы просто хотите сказать "Go do something", и вам все равно, когда/если он завершится, и он не имеет возвращаемого значения. Если вы хотите увидеть возвращаемое значение и знаете, когда что-то завершено, используйте задачи.

Я настоятельно рекомендую CLR через С# Jeffrey Richer. Он имеет отличный раздел для потоковой передачи и различные способы их использования в вашем.Net-коде.

2

То, как вы в настоящее время ожидаете завершения потока, выглядит прекрасным - нити умирают, когда заканчивается код, и Join гарантирует, что он закончил.

Вы не можете перезапустить поток, но вам придется создать новый.

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

2

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();
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню