我有以下代码。我正在尝试为主窗体创建按钮,可以暂停,继续并停止下载器运行的后台线程(私有线程线程)
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
}
问题是按暂停按钮会冻结主窗体而不是后台线程。
答案 0 :(得分:4)
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以来,有更好的方法来管理线程取消,即使用CancellationTokenSource
和CancellationToken
。
有关详细信息,请参阅this Microsoft article。