Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/263.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#暂停主线程的工作线程_C#_Multithreading - Fatal编程技术网

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所有已经解包的文件?您只需要有一个控件。这不是我的意思,卸载行为可以正常工作,在安装和中止安装以及卸载解包的文件之间,有一段代码,我暂停线程以查看用户是否确认要取消安装种马过程。