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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/382173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:21:48  来源:igfitidea点击:

What are alternative ways to suspend and resume a thread?

c#.net-2.0thread-safety

提问by David.Chu.ca

The two methods Thread.Suspend()and Thread.Resume()are obsolete since .NET 2.0. Why? What are other alternatives and any examples?

这两种方法Thread.Suspend()Thread.Resume()是因为.NET 2.0过时。为什么?什么是其他选择和任何例子?

回答by Patrick Desjardins

This is the best tutorial ever for Thread (for C#): http://www.albahari.com/threading/

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

For wait you need to use .Join() on the thread. This will wait until tread finish is job. Other wise you will need to use Wait/Pulse.

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

回答by Daniel Earwicker

The good alternatives all work by the thread reaching a point where it is happy to wait. Suspend was dangerous because it could suspend the thread while it was holding a lock on a mutex - a recipe for deadlocks.

好的替代方案都是由线程达到一个愿意等待的点来工作的。挂起是危险的,因为它可以在线程持有互斥锁时挂起线程 - 这是死锁的一个秘诀。

So what your thread needs is a ManualResetEvent that it can Wait on - at a time when it is safe for it to do so, when it is not holding any locks.

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

回答by Szymon Rozga

I agree that is a great tutorial. The main reason Suspend() and Resume() are obsolete is because they are pretty dangerous methods. At any point Thread t could be doing anything. Anything. Imagine your thread is reading a file and has a lock on it. You suspend your thread. File stays locked. Same goes for any other resources. Same goes for a lock on a mutex.

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

回答by David.Chu.ca

That one is too long. What I need is a quick example codes to use. I found one from the discussion and answered by Mark R. Dawson at http://bytes.com/groups/net-c/458947-thread-suspend. It explains the danger of the obsolete methods and how to use AutoResetEvent to notify the second thread to continue processing.

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

回答by Darcy Casselman

You'll want to use an AutoResetEvent EventWaitHandle.

您需要使用 AutoResetEvent EventWaitHandle。

Say you want to do something like this (NOTE: don't do this!):

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

private Thread myThread;

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

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

Like others have said, this is a bad idea. Even though only using Suspend on its own thread is relatively safe, you can never figure out if you're calling Resume when the thread is actually suspended. So Suspend and Resume have been obsoleted.

正如其他人所说,这是一个坏主意。尽管仅在其自己的线程上使用 Suspend 相对安全,但您永远无法确定是否在线程实际挂起时调用了 Resume。所以 Suspend 和 Resume 已经过时了。

Instead, you want to use an AutoResetEvent:

相反,您想使用 AutoResetEvent:

private EventWaitHandle wh = new AutoResetEvent();

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

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

The worker thread will wait on the wait handle until another thread calls StartWorking. It works much the same as Suspend/Resume, as the AutoResetEvent only allows one thread to be "resumed".

工作线程将等待等待句柄,直到另一个线程调用 StartWorking。它的工作方式与 Suspend/Resume 非常相似,因为 AutoResetEvent 只允许“恢复”一个线程。

回答by Luke

you can use ManualReset instead of AutoReset:

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

 }
 }
}

回答by Peter O.

The reasons why Thread.Suspend()and Thread.Resume()are obsolete or removed in .NET are largely the same reasons why Thread.suspend()and Thread.resume()are obsolete in Java. Compare—

为什么原因Thread.Suspend()Thread.Resume()已过时或.NET删除很大程度上是相同的原因Thread.suspend(),并Thread.resume()在Java过时。相比-

回答by Doug Null

Solution: Have a thread only resume another thread if the other thread has suspended itself. Thus, the first thread only resumes the other thread if the other thread suspended itself (ie. its ThreadState = Suspended), and, thus, made itself ready to be resumed. This seems safe & flawless.

解决方案:让一个线程仅在另一个线程自己挂起时恢复另一个线程。因此,第一个线程仅在另一个线程挂起自身(即其 ThreadState = Suspended)时才恢复另一个线程,并因此准备好恢复。这似乎是安全和完美的。

Or, am I not understanding .Net threading?

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