不确定我的标题措辞是否合适,但无论如何:)
我有两个主题:需要完成工作的主线程,以及包含带进度条和取消按钮的表单的工作线程。在普通代码中,它将是另一种方式,但在这种情况下我不能这样做。
当用户点击取消按钮时,会显示一个提示,询问他是否要真正取消工作。问题是主线程上的工作仍在继续。我可以让主线程停止工作等等,但我希望它在提示单击“是”时停止工作。
示例:
// Main thread work starts here
t1 = new Thread(new ThreadStart(progressForm_Start));
t1.Start();
// Working
for (i = 0; i <= 10000; i++)
{
semaphore.WaitOne();
if (pBar.Running)
bgworker_ProgressChanged(i);
semaphore.Release();
if (pBar.IsCancelled) break;
}
t1.Abort();
// Main thread work ends here
// Start progress bar form in another thread
void progressForm_Start()
{
pBar.Status("Starting");
pBar.ShowDialog();
}
理论上我可以在cancelWatch()函数中包含一个提示符,但是在我实现这个类的任何地方我都必须这样做。
答案 0 :(得分:2)
我有几个快速评论:
Thread.Abort()
here's why。Thread.IsBackground = true
(当您的应用程序退出时,这将自动退出该主题)。以下是有关如何安全停止线程运行的详细讨论:Is it safe to use a boolean flag to stop a thread from running in C#
要停止主线程的工作,你必须做这样的事情:
boolean volatile isRunning = true;
static void Main(...)
{
// ...
// Working
for (i = 0; i <= 10000; i++)
{
semaphore.WaitOne();
if (!isRunning) break; // exit if not running
if (pBar.Running)
bgworker_ProgressChanged(i);
semaphore.Release();
}
//...
t1.Interrupt();// make the worker thread catch the exception
}
//
void cancelButton_Click(object sender, EventArgs e)
{
isRunning = false; // optimistic stop
semaphore.Release();
}
答案 1 :(得分:1)
我建议使用CancellationTokenSource,它可以处理这种复杂的情况。它是任务并行库的一部分,但实际上不必与Task
个对象一起使用;它可以很容易地与旧式Thread
对象一起使用。
当然,如果你有时间,我建议将主线程的工作定义为Task
对象(使用TaskScheduler.FromCurrentSynchronizationContext
在主UI线程上运行)。
请注意,以上所有内容均假定为.NET 4.0。如果您仍然停留在旧平台上,则只需要bool cancelled;
字段保护lock
或某些此类内容。提示:请勿致电Thread.Abort
;这是邪恶的。