什么是暂停和恢复线程的替代方法?

时间:2008-12-19 20:52:42

标签: c# .net-2.0 thread-safety

自.NET 2.0以来,Thread.Suspend()Thread.Resume()这两种方法已经过时了。为什么?什么是其他替代品和任何例子?

8 个答案:

答案 0 :(得分:20)

您需要使用AutoResetEvent EventWaitHandle。

说你想做这样的事情(注意:不要这样做!):

private Thread myThread;

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

public void StartWorking() 
{
    myThread.Resume();
}
像其他人说的那样,这是一个坏主意。尽管只在自己的线程上使用Suspend是相对安全的,但是当线程实际被挂起时,你永远无法弄清楚你是否正在调用Resume。所以Suspend and Resume已经过时了。

相反,您想要使用AutoResetEvent:

private EventWaitHandle wh = new AutoResetEvent();

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

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

工作线程将等待等待句柄,直到另一个线程调用StartWorking。它与Suspend / Resume的工作原理大致相同,因为AutoResetEvent只允许一个线程“恢复”。

答案 1 :(得分:11)

良好的替代方案都可以通过线程达到高兴等待的程度。暂停是危险的,因为它可以在线程锁定互斥锁时挂起线程 - 这是死锁的一个秘诀。

那么你的线程需要的是一个可以等待的ManualResetEvent - 当它没有持有任何锁时,它可以安全地执行此操作。

答案 2 :(得分:4)

这是Thread(适用于C#)的最佳教程:http://www.albahari.com/threading/

等待你需要在线程上使用.Join()。这将等到胎面完成工作。另外,你需要使用Wait/Pulse

答案 3 :(得分:2)

您可以使用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");

 }
 }
}

答案 4 :(得分:1)

那个太长了。我需要的是一个快速的示例代码。我在讨论中找到了一个并由Mark R. Dawson在http://bytes.com/groups/net-c/458947-thread-suspend回答。它解释了过时方法的危险以及如何使用AutoResetEvent通知第二个线程继续处理。

答案 5 :(得分:0)

我同意这是一个很棒的教程。 Suspend()和Resume()过时的主要原因是因为它们是非常危险的方法。在任何时候,线程t都可以做任何事情。任何东西。想象一下,你的线程正在读取文件并对其进行锁定。你暂停你的线程。文件保持锁定状态任何其他资源也是如此。同样可以锁定互斥锁。

答案 6 :(得分:0)

.NET中Thread.Suspend()Thread.Resume()被淘汰或删除的原因与Java中Thread.suspend()Thread.resume()被淘汰的原因大致相同。比较—

答案 7 :(得分:0)

解决方案: 仅当另一个线程已挂起自身时,才让该线程继续另一个线程。 因此,如果另一个线程自身挂起(即其ThreadState = Suspended),则第一个线程仅恢复另一个线程,从而使自己准备好恢复。这似乎是安全无瑕的。

或者,我是否不了解.Net线程?