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

本文关键字:暂停 后台 线程 set AutoResetEvent 使用 WaitOne | 更新日期: 2023-09-27 18:09:19

我有以下代码。我正试图使按钮的主要形式,可以暂停,继续和停止后台线程下载程序正在运行(私有线程线程)

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();
        }

此代码在Windows窗体上运行。我有用于所有动作的按钮(暂停,继续,停止)

暂停和继续按钮在表单

上有代码
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
    }

问题是按下暂停按钮将冻结主窗体而不是后台线程。

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

必须能够暂停的是runDownloader()

需要在等待句柄上周期性地调用waitHandle.WaitOne()

你的WaitHandle必须是一个ManualResetEvent,而不是一个AutoResetEvent,你应该初始化它,这样它是有信号的(除非你想开始你的线程在一个"暂停"状态)。

您还必须更改按钮处理程序,如下所示:

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
}

这意味着你必须能够将waitHandle传递给线程,以便它可以等待它。

然而,自。net 4以来,有更好的方法来管理线程取消,即使用CancellationTokenSourceCancellationToken