29

从 .NET 2.0 开始Thread.Suspend(),这两种方法都已过时。Thread.Resume()为什么?还有哪些其他选择和示例?

4

8 回答 8

22

您需要使用 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 和 Resume 已经过时了。

相反,您想使用 AutoResetEvent:

private EventWaitHandle wh = new AutoResetEvent();

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

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

工作线程将在等待句柄上等待,直到另一个线程调用 StartWorking。它的工作原理与暂停/恢复非常相似,因为 AutoResetEvent 只允许“恢复”一个线程。

于 2009-04-15T19:18:55.310 回答
12

好的替代方案都是通过线程达到它乐于等待的点来工作的。挂起是危险的,因为它可能会在线程持有互斥锁时挂起线程 - 这是死锁的秘诀。

因此,您的线程需要的是一个可以等待的 ManualResetEvent - 在它可以安全地这样做的时候,当它没有持有任何锁时。

于 2008-12-19T20:58:38.860 回答
5

这是有史以来最好的 Thread 教程(用于 C#):http ://www.albahari.com/threading/

对于等待,您需要在线程上使用 .Join() 。这将等到胎面完成工作。否则,您将需要使用Wait/Pulse

于 2008-12-19T20:57:09.487 回答
3

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

 }
 }
}
于 2015-09-15T09:01:36.730 回答
1

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

于 2008-12-19T21:12:13.263 回答
0

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

于 2008-12-19T20:59:23.447 回答
0

.NET 中过时或删除的原因与Thread.Suspend()Java中过时和过时的原因基本相同。相比-Thread.Resume()Thread.suspend()Thread.resume()

于 2018-11-25T02:15:11.767 回答
0

解决方案:只有当另一个线程自己挂起时,才让一个线程恢复另一个线程。因此,第一个线程仅在另一个线程暂停自身(即其 ThreadState = Suspended)时才恢复另一个线程,从而使自己准备好恢复。这似乎安全无瑕。

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

于 2019-10-08T15:04:04.037 回答