Подтвердить что ты не робот

Каковы альтернативные способы приостановить и возобновить поток?

Два метода Thread.Suspend() и Thread.Resume() устарели с .NET 2.0. Зачем? Каковы другие альтернативы и любые примеры?

4b9b3361

Ответ 1

Вы хотите использовать AutoResetEvent EventWaitHandle.

Предположим, вы хотите сделать что-то вроде этого ( ПРИМЕЧАНИЕ: не делайте этого!):

private Thread myThread;

private void WorkerThread() 
{
    myThread = Thread.CurrentThread;
    while (true)
    {
        myThread.Suspend();
        //Do work.
    }
}

public void StartWorking() 
{
    myThread.Resume();
}

Как говорили другие, это плохая идея. Несмотря на то, что использование Suspend только в собственном потоке относительно безопасно, вы никогда не сможете определить, будет ли вы возобновлять вызов, когда поток фактически приостановлен. Поэтому Suspend и Resume были устарели.

Вместо этого вы хотите использовать AutoResetEvent:

private EventWaitHandle wh = new AutoResetEvent();

private void WorkerThread() 
{
    while(true) 
    {
        wh.WaitOne();
        //Do work.
    }
}

public void StartWorking()
{
    wh.Set();
}

Рабочий поток будет ждать команды wait, пока другой поток не вызовет StartWorking. Он работает так же, как Suspend/Resume, поскольку AutoResetEvent позволяет только один поток "возобновиться".

Ответ 2

Хорошие альтернативы работают по потоку, достигая точки, в которой он счастлив ждать. Приостановка опасна, потому что она может приостановить нить, пока она удерживает блокировку на мьютексе - рецепт тупиков.

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

Ответ 3

Это лучший учебник для Thread (для С#): http://www.albahari.com/threading/

Для ожидания вам нужно использовать .Join() в потоке. Это будет ждать, пока закончится протекция. В другом случае вам нужно будет использовать Wait/Pulse.

Ответ 4

Этот слишком длинный. Мне нужен код быстрого кода для использования. Я нашел один из обсуждения и ответил Марк Р. Доусон на http://bytes.com/groups/net-c/458947-thread-suspend. Это объясняет опасность устаревших методов и использование AutoResetEvent для уведомления второго потока для продолжения обработки.

Ответ 5

вы можете использовать ManualReset вместо AutoReset:

public class Worker
{
 ManualResetEvent _shutdownEvent = new ManualResetEvent(false);
 ManualResetEvent _pauseEvent = new ManualResetEvent(true);
 Thread _thread;

public Worker() { }

public void Start()
 {
 _thread = new Thread(DoWork);
 _thread.Start();
 Console.WriteLine("Thread started running");
 }

public void Pause()
 {
 _pauseEvent.Reset();
 Console.WriteLine("Thread paused");
 }

public void Resume()
 {
 _pauseEvent.Set();
 Console.WriteLine("Thread resuming ");
 }

public void Stop()
 {
 // Signal the shutdown event
 _shutdownEvent.Set();
 Console.WriteLine("Thread Stopped ");

// Make sure to resume any paused threads
 _pauseEvent.Set();

// Wait for the thread to exit
 _thread.Join();
 }

public void DoWork()
 {
 while (true)
 {
 _pauseEvent.WaitOne(Timeout.Infinite);

if (_shutdownEvent.WaitOne(0))
 break;

// Do the work..
 Console.WriteLine("Thread is running");

 }
 }
}

Ответ 6

Я согласен, что это отличный учебник. Основная причина Suspend() и Resume() устарела, потому что они довольно опасные методы. В любой момент Thread t может делать что угодно. Что-нибудь. Представьте, что ваш поток читает файл и имеет блокировку. Вы приостанавливаете свою нить. Файл остается заблокированным. То же самое касается любых других ресурсов. То же самое касается блокировки мьютекса.