所以,我想从主线程中暂停一个工作线程,如果我决定,我希望能够恢复它的活动。在此之前,我使用了myThread.Suspend()
和Resume()
,但它已经已弃用而且不推荐不再使用它。
你们中有人能给我一个替代吗? 谢谢!
答案 0 :(得分:2)
一种方法是使用ManualResetEvent
或AutoResetEvent
对象。等待信号的线程将阻塞,直到某些事件将调用事件对象上的Set()。
当然,这仅适用于控制在工作线程中执行的循环。
private ManualResetEvent runningWork = new ManualResetEvent(true);
public void Main()
{
//
// suspend
runningWork.Reset();
// resume
runningWork.Set();
//
}
public void Work()
{
// long task
while (!stop)
{
runningWork.WaitOne(/* optional timeout */);
//worker task
}
}
答案 1 :(得分:0)
我认为你错过了重点。不推荐使用Thread.Pause
和Thread.Resume
的原因是使用它们会导致一系列问题。无论线程在做什么,调用Thread.Pause
都会在其轨道中暂停一个线程。它可能持有一把锁。只要它被暂停,它将继续保持锁定状态。它可能正在复制文件,执行数据库更新,执行时间关键任务,更新共享数据结构等。在任何这些或许多其他任务期间暂停线程可能会使程序,数据库,文件系统,甚至可能是处于不一致状态的操作系统。如果然后中止该线程,则会使该不一致状态成为永久状态。
换句话说,不要这样做。
如果您希望能够暂停和恢复线程,则需要对线程进行编码,以便它知道它可以暂停。你需要让它在暂停时合作。因此,不要在其轨道中停止线程,而是告诉线程您希望它尽早停止。
我所知道的最简单的方法是使用ManualResetEvent。这里的想法是您在设置状态下初始化事件。如果希望线程暂停,则清除该事件。然后在希望线程恢复时再次设置它。例如:
ManualResetEvent OkayToContinue = new ManualResetEvent(true);
// in your main thread
Thread myThread = CreateWorkerThread(...); // however you do that.
// pause the thread . . .
OkayToContinue.Reset();
// do whatever you want to do while the thread is suspended
// And then restart the thread
OkayToContinue.Set();
在工作线程中:
while (!done)
{
// make sure it's safe to continue
OkayToContinue.WaitOne();
// do next step . . .
}
现在,如果您希望线程终止,通常使用CancellationToken。为此,您可以将其添加到主程序中:
CancellationTokenSource CancelToken = new CancellationTokenSource();
通常,您将CancelTokenSource.Token
传递给线程,以便它无法访问CancelletionTokenSource对象,但是对于此示例,我将通过父对象。
// in your thread proc
do
{
// do next step
// Then check to see if paused or canceled
OkayToContinue.WaitOne();
} while (!done && !CancelToken.Token.IsCancellationRequested);
这里的关键是你不要从线下拉出地毯。相反,你要告诉线程优雅地关闭。
答案 2 :(得分:-1)
private BackgroundWorker _bgWorker = new BackgroundWorker();
public void Main(string[] args)
{
_bgWorker.DoWork += _bgWorker_DoWork;
// We want to be able to cancel our installation, for whatever reason.
_bgWorker.SupportsCancellation = true;
_bgWorker.RunWorkerAsync();
}
private void _bgWorker_DoWork(object sender, DoWorkEventArgs e)
{
while (!_bgWorker.CancellationPending)
{
// Do things for your install here.
}
// Display your dialog asking if they'd like to continue.
if (!userWantsToContinue)
{
// Do rollback logic here.
return;
}
else
{
// Do the rest of your install.
}
}
这是使用BackgroundWorker执行此操作的粗略抛出示例,而不是您必须管理的单独线程。 BackgroundWorker还具有报告事件进度和使用事件报告线程工作完成的额外好处。
https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx