[英]C# Pause a working thread from the main thread
所以,我想从主线程暂停一个工作线程,如果我决定,我希望能够恢复它的活动。 之前,我使用了myThread.Suspend()
和Resume()
但它已被弃用,不建议再使用它。
你们中的任何人都可以给我一个替代方案吗? 谢谢!
一种方法是使用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
}
}
我认为你没有抓住重点。 不推荐使用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);
这里的关键是你不是从线下拉出地毯。 相反,您是在告诉线程优雅地关闭。
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.