繁体   English   中英

C#从主线程暂停一个工作线程

[英]C# Pause a working thread from the main thread

所以,我想从主线程暂停一个工作线程,如果我决定,我希望能够恢复它的活动。 之前,我使用了myThread.Suspend()Resume()但它已被弃用不建议再使用它。

你们中的任何人都可以给我一个替代方案吗? 谢谢!

一种方法是使用ManualResetEventAutoResetEvent对象。 等待信号的线程将被阻塞,直到某事将在事件对象上调用 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.PauseThread.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM