Два метода Thread.Suspend()
и Thread.Resume()
устарели с .NET 2.0. Зачем? Каковы другие альтернативы и любые примеры?
Каковы альтернативные способы приостановить и возобновить поток?
Ответ 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 может делать что угодно. Что-нибудь. Представьте, что ваш поток читает файл и имеет блокировку. Вы приостанавливаете свою нить. Файл остается заблокированным. То же самое касается любых других ресурсов. То же самое касается блокировки мьютекса.