[英]how to pause/resume a thread
如何暂停/恢复线程? 一旦我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#Threading ,特别是Suspend and Resume部分:
可以通过不赞成使用的方法Thread.Suspend和Thread.Resume显式地挂起和恢复线程。 这种机制与阻塞是完全分开的。 两种系统都是独立的,并且可以并行运行。
一个线程可以挂起自身或另一个线程。 调用Suspend会导致线程短暂进入SuspendRequested状态,然后到达可以安全进行垃圾回收的点时,它将进入Suspended状态。 从那里开始,只能通过另一个调用其Resume方法的线程来恢复它。 恢复仅适用于挂起的线程,而不适用于阻塞的线程。
从.NET 2.0开始,不赞成使用Suspend和Resume,因为任意地挂起另一个线程具有固有的危险,因此不建议使用它们。 如果暂停了关键资源锁的线程,则整个应用程序(或计算机)可能会死锁。 这比调用Abort危险得多,后者会导致通过调用finally块中的代码(至少在理论上)释放任何此类锁。
手动挂起和恢复线程不是最好的主意。 但是,您可以使用线程同步原语(例如ManualResetEvent )轻松模拟此行为。
看一下这个问题 ,您会发现它很有帮助。
但我相信您可以通过使用计时器轻松地实现“在标签控件中显示随机文本”的目标。
这是使用DispatcherTimer的快速示例
var timer = new DispatcherTimer();
timer.Tick += (s, e) => Label.Text = GetRandomText();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Start();
你可以通过调用暂停timer.Stop()
然后timer.Start()
再次恢复。
这是为我工作的两种方法。 两者都假定工作线程具有其自己的处理循环。
下面的控制台应用程序示例显示了两种方法:使用回调暂停/继续和使用工作方方法停止。 回调方法的另一个优点是,在检查继续权限时,还可以方便地回传状态更新。
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;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.