自.NET 2.0以来,Thread.Suspend()
和Thread.Resume()
这两种方法已经过时了。为什么?什么是其他替代品和任何例子?
答案 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()
被淘汰的原因大致相同。比较—
suspend
“天生容易死锁”),答案 7 :(得分:0)
解决方案: 仅当另一个线程已挂起自身时,才让该线程继续另一个线程。 因此,如果另一个线程自身挂起(即其ThreadState = Suspended),则第一个线程仅恢复另一个线程,从而使自己准备好恢复。这似乎是安全无瑕的。
或者,我是否不了解.Net线程?