简体   繁体   English

使用AutoResetEvent.WaitOne()和.Set()暂停后台线程

[英]Pausing background thread with AutoResetEvent.WaitOne() and .Set()

I have following code. 我有以下代码。 I'm trying to make buttons to main Form which can Pause, Continue and Stop the background thread the downloader is running on (private Thread thread) 我正在尝试为主窗体创建按钮,可以暂停,继续并停止下载器运行的后台线程(私有线程线程)

Form1.cs Form1.cs的

private AutoResetEvent waitHandle = new AutoResetEvent(true);
private Thread thread;

        private void ThreadJob()
        {
            Downloader download = new Downloader();
            download.runDownloader();
        }

        // THREADS button1 is "Download now"-button
        private void button1_Click(object sender, EventArgs e)
        {
            ThreadStart job = new ThreadStart(ThreadJob);
            thread = new Thread(job);
            thread.IsBackground = true;
            thread.Start();
        }

This code is ran on Windows Form. 此代码在Windows窗体上运行。 I have buttons for all those actions (Pause, Continue, Stop) 我有所有这些动作的按钮(暂停,继续,停止)

Pause and continue button has code on form 暂停和继续按钮在表单上有代码

private void btnPause_Click(object sender, EventArgs e)
{
    waitHandle.WaitOne(); // Need to pause the background thread
}

 private void btnContinue_Click(object sender, EventArgs e)
    {
        waitHandle.Set(); // Need to continue the background thread
    }

The problem is pressing Pause button will freeze the main Form not the background thread. 问题是按暂停按钮将冻结主窗体而不是后台线程。

It is runDownloader() that must be able to pause. runDownloader()必须能够暂停。

It will need to periodically call waitHandle.WaitOne() on the wait handle. 它需要定期在wait句柄上调用waitHandle.WaitOne()

Your WaitHandle must be a ManualResetEvent , not an AutoResetEvent and you should initialise it so that it is signalled (unless you want to start your thread in a "paused" state). 您的WaitHandle必须是ManualResetEvent ,而不是AutoResetEvent ,您应该初始化它以便发出信号(除非您想要以“暂停”状态启动线程)。

You will also have to change your button handlers as follows: 您还必须按如下方式更改按钮处理程序:

private void btnPause_Click(object sender, EventArgs e)
{
    waitHandle.Reset(); // Need to pause the background thread
}

private void btnContinue_Click(object sender, EventArgs e)
{
    waitHandle.Set(); // Need to continue the background thread
}

This means that you must be able to pass waitHandle to the thread so that it can wait on it. 这意味着您必须能够将waitHandle传递给线程,以便它可以等待它。

However, there are better ways of managing thread cancellation since .Net 4, namely the use of CancellationTokenSource and CancellationToken . 但是,自.Net 4以来,有更好的方法来管理线程取消,即使用CancellationTokenSourceCancellationToken

See this Microsoft article for details. 有关详细信息,请参阅此Microsoft文章

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在单元测试中设置 AutoResetEvent.WaitOne() 的方法 - A way to set AutoResetEvent.WaitOne() in a unit test AutoResetEvent.WaitOne,超时与Thread.Sleep - AutoResetEvent.WaitOne with timeout vs Thread.Sleep AutoResetEvent.WaitOne()导致死锁 - AutoResetEvent.WaitOne() cause deadlock 在AutoResetEvent.WaitOne()时呈现用户控件 - Render Usercontrol while AutoResetEvent.WaitOne() C#中的AutoResetEvent.WaitOne()方法返回值 - AutoResetEvent.WaitOne() method return value in C# 检查控制变量后调用AutoResetEvent.WaitOne - Calling AutoResetEvent.WaitOne after checking a control variable 创建一个使用TimeSpan使用AutoResetEvent.WaitOne迭代1ms以下的循环 - Creating a loop which iterate below 1ms using AutoResetEvent.WaitOne with TimeSpan 击中AutoResetEvent的WaitOne()后清除多个设置 - Clear multiple set after hitting the WaitOne() of AutoResetEvent 由于 WaitOne state 中的 AutoResetEvent 信号,应用程序终止后线程仍然存在 - Thread persists after application termination due to AutoResetEvent signal in WaitOne state 当第二个线程都调用WaitOne()并由AutoResetEvent释放时,为什么第二个线程在第一个线程之前释放? - Why does the second thread get released before the first one, when they both called WaitOne() and were released by an AutoResetEvent?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM