我在使用.NET 4.0进行并行编程时显然不知所措。我有一个简单的Windows应用程序,启动一个任务来执行一些无聊的工作(输出1-1000的数字)。我在中途放了一个长时间的暂停来模拟长时间运行的过程。当这个长时间的暂停正在进行时,如果我点击Stop按钮,它的事件处理程序将调用CancellationTokenSource的Cancel方法。在取消任务完成当前迭代之前,我不想在Stop按钮的事件处理程序中执行任何进一步的处理(在本例中,输出一条消息)。如何做到这一点?我尝试在Stop按钮的事件处理程序中使用Task.WaitAll等方法,但那只会抛出未处理的AggregateException异常。以下是代码,将在按照上述方式运行时帮助说明我的问题:
private Task t;
private CancellationTokenSource cts;
public Form1()
{
InitializeComponent();
}
private void startButton_Click(object sender, EventArgs e)
{
statusTextBox.Text = "Output started.";
// Create the cancellation token source.
cts = new CancellationTokenSource();
// Create the cancellation token.
CancellationToken ct = cts.Token;
// Create & start worker task.
t = Task.Factory.StartNew(() => DoWork(ct), ct);
}
private void DoWork(CancellationToken ct)
{
for (int i = 1; i <= 1000; i++)
{
ct.ThrowIfCancellationRequested();
Thread.Sleep(10); // Slow down for text box outout.
outputTextBox.Invoke((Action)(() => outputTextBox.Text = i + Environment.NewLine));
if (i == 500)
{
Thread.Sleep(5000);
}
}
}
private void stopButton_Click(object sender, EventArgs e)
{
cts.Cancel();
Task.WaitAll(t); // this doesn't work :-(
statusTextBox.Text = "Output ended.";
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
非常感谢您对此的帮助。提前致谢。
ae.Handle<OperationCanceledException>(ce => true);
应该改为:ae.Handle(x => x is OperationCanceledException);
我认为Reed可能有一个允许类型参数的扩展方法。 - Metro Smurf