C#暂停主线程的工作线程
因此,我想暂停主线程的一个工作线程,如果我决定暂停,我想能够恢复它的活动。以前,我使用了C#暂停主线程的工作线程,c#,multithreading,C#,Multithreading,因此,我想暂停主线程的一个工作线程,如果我决定暂停,我想能够恢复它的活动。以前,我使用了myThread.Suspend()和Resume(),但它已被弃用,不建议再使用它 你们谁能给我一个选择吗? 谢谢 一种方法是使用ManualResetEvent或AutoResetEvent对象。等待信号的线程将阻塞,直到有东西调用事件对象上的Set() // in your thread proc do { // do next step // Then check to see if
myThread.Suspend()
和Resume()
,但它已被弃用,不建议再使用它
你们谁能给我一个选择吗?
谢谢 一种方法是使用
ManualResetEvent
或AutoResetEvent
对象。等待信号的线程将阻塞,直到有东西调用事件对象上的Set()
// in your thread proc
do
{
// do next step
// Then check to see if paused or canceled
OkayToContinue.WaitOne();
} while (!done && !CancelToken.Token.IsCancellationRequested);
当然,这仅适用于控制在辅助线程中执行的循环的情况
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
}
}
这是一个使用BackgroundWorker来完成这项工作的粗略组合示例,而不是您必须管理的单独线程。BackgroundWorker还有另外一个好处,即通过事件报告进度,并通过事件报告线程工作完成情况
我认为你没有抓住重点。
Thread.Pause
和Thread.Resume
被弃用的原因是使用它们会导致一系列问题。调用Thread.Pause
会暂停线程的轨迹,而不管线程正在做什么。它可能拿着一把锁。它将继续持有该锁,直到它被挂起为止。它可能在复制文件、进行数据库更新、执行时间关键任务、更新共享数据结构等的过程中。在这些或任何其他任务中停顿一个线程,可能会使程序、数据库、文件系统或甚至操作系统处于不一致的状态。如果随后中止线程,则会使该不一致状态永久化
换句话说,不要那样做
如果希望暂停和恢复线程,则需要对线程进行编码,以便它知道可以暂停线程。你需要让它配合暂停。因此,不要停止线程的运行,而是告诉线程希望它在最早的安全时机停止
我所知道的最简单的方法就是使用。这里的想法是在设置状态下初始化事件。如果希望线程暂停,请清除事件。然后在希望线程恢复时再次设置它。例如:
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 . . .
}
现在,如果希望线程终止,通常使用。为此,请将以下内容添加到主程序:
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);
这里的关键是你没有把地毯从线下拔出来。相反,您告诉线程要优雅地关闭。现代的方法是重新设计线程以使用同步对象,然后通过锁定来自主线程的互斥锁来控制线程。出现此警告是有原因的。不推荐暂停线程。您想做什么?为什么要暂停线程?那总是一个糟糕的设计。您可以使用事件来发出停止处理的信号。更好的方法是重写代码,这样就不需要暂停。来自MSDN:因为Thread.Suspend和Thread.Resume不依赖于被控制线程的协作,它们具有高度侵入性,可能导致严重的应用程序问题,如死锁(例如,如果挂起一个线程,该线程持有另一个线程将需要的资源)。我个人建议对I/O密集型任务使用async/Wait,或者使用BackgroundWorker类。我有一个监控应用程序,它使用多个BackgroundWorker监控数据库连接,我发现它远远优于手动线程管理。我无法控制线程所做的工作,这就是y我问了一些我可以用来从外面暂停的东西。@dizzyOWNZ这正是你不应该这样做的原因。你不知道如果这样做会发生什么。这就是为什么
Suspend()
和Resume()
有这些警告。你想做什么?我在安装程序中使用它,当退出确认窗口出现时,线程被暂停,如果用户确认退出,线程被中止,如果他决定继续,线程被恢复。你知道,如果确认退出,你应该支持这种行为,例如uninsta所有已经解包的文件?您只需要有一个控件。这不是我的意思,卸载行为可以正常工作,在安装和中止安装以及卸载解包的文件之间,有一段代码,我暂停线程以查看用户是否确认要取消安装种马过程。