如何暂停/恢复一个post

如何暂停/恢复线程? 一旦我Join()一个线程,我就无法重启它。 那么,每当按下按钮“暂停”时,如何启动一个线程并使其暂停,并在按下恢复按钮时恢复它?

这个线程唯一能做的就是在标签控件中显示一些随机文本。

也许ManualResetEvent是一个不错的选择。 一个简短的例子:

 private static EventWaitHandle waitHandle = new ManualResetEvent(initialState: true); // Main thread public void OnPauseClick(...) { waitHandle.Reset(); } public void OnResumeClick(...) { waitHandle.Set(); } // Worker thread public void DoSth() { while (true) { // show some random text in a label control (btw. you have to // dispatch the action onto the main thread) waitHandle.WaitOne(); // waits for the signal to be set } } 

我建议你阅读Joe Albahari的C#中的线程 ,特别是Suspend and Resume部分:

可以通过弃用的方法Thread.Suspend和Thread.Resume显式挂起和恢复线程。 这种机制与阻塞机制完全分开。 两个系统都是独立的并且并行运行。

线程可以挂起自己或其他线程。 调用Suspend导致线程暂时进入SuspendRequested状态,然后在达到垃圾收集安全点时,它进入Suspended状态。 从那里,它只能通过另一个调用其Resume方法的线程来恢复。 Resume只能在挂起的线程上工作,而不是阻塞的线程。

从.NET 2.0开始,Suspend和Resume已被弃用,由于任意暂停另一个线程所固有的危险,因此不鼓励使用它们。 如果暂停对关键资源进行锁定的线程,则整个应用程序(或计算机)可能会死锁。 这比调用Abort更危险 – 这导致任何这样的锁通过finally块中的代码被释放(至少在理论上)。

SuspendRequested状态

手动挂起和恢复线程并不是最好的主意。 但是,您可以使用线程同步原语(如ManualResetEvent )轻松模拟此行为

看看这个问题 ,你会发现它很有帮助。

但我相信您可以通过使用计时器轻松实现“在标签控件中显示随机文本”的目标。

以下是使用DispatcherTimer的快速示例

 var timer = new DispatcherTimer(); timer.Tick += (s, e) => Label.Text = GetRandomText(); timer.Interval = TimeSpan.FromMilliseconds(500); timer.Start(); 

您可以通过调用timer.Stop()然后再次使用timer.Stop()来暂停它。

这有两种方式对我有用。 两者都假设工作线程有自己的处理循环。

  1. 让线程调用回调来请求继续使用的权限
  2. 让父进程调用线程类的方法来发信号

下面的控制台应用程序示例显示了两种方法,使用回调暂停/继续,以及要停止的工作方法。 回调方法的另一个优点是,在检查是否允许继续时,还可以方便地传回状态更新。

 using System; using System.Threading; namespace ConsoleApplication7 { class Program { static bool keepGoing; static void Main(string[] args) { keepGoing = true; Worker worker = new Worker(new KeepGoingDelegate(KeepGoing)); Thread thread = new Thread(worker.DoWork); thread.IsBackground = true; thread.Start(); while (thread.ThreadState != ThreadState.Stopped) { switch (Console.ReadKey(true).KeyChar) { case 'p': keepGoing = false; break; case 'w': keepGoing = true; break; case 's': worker.Stop(); break; } Thread.Sleep(100); } Console.WriteLine("Done"); Console.ReadKey(); } static bool KeepGoing() { return keepGoing; } } public delegate bool KeepGoingDelegate(); public class Worker { bool stop = false; KeepGoingDelegate KeepGoingCallback; public Worker(KeepGoingDelegate callbackArg) { KeepGoingCallback = callbackArg; } public void DoWork() { while (!stop) { Console.Write(KeepGoingCallback()?"\rWorking":"\rPaused "); Thread.Sleep(100); } Console.WriteLine("\nStopped"); } public void Stop() { stop = true; } } }