Mac*_*Mac 23 .net parallel-processing c#-4.0
在使用.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();
}
Run Code Online (Sandbox Code Playgroud)
任何有关这方面的帮助将不胜感激.提前致谢.
Ree*_*sey 10
您通常只使用Task.Wait(而不是WaitAll),因为它是一项任务.然后适当地处理异常:
private void stopButton_Click(object sender, EventArgs e)
{
cts.Cancel();
try
{
t.Wait(); // This will throw
}
catch (AggregateException ae)
{
ae.Handle<OperationCanceledException>(ce => true);
}
statusTextBox.Text = "Output ended.";
}
Run Code Online (Sandbox Code Playgroud)
当你取消a时Task,一旦你打电话或试图获得任务(如果它是a ),OperationCanceledException它将被包裹成一个AggregateException并被抛出.Wait()ResultTask<T>
纯粹是为了您的信息 - 这是一个地方,特别是考虑到您在这里所做的事情,C#5简化了事情.使用新的异步支持,您可以将其写为:
// No need for "t" variable anymore
// private Task t;
private async void startButton_Click(object sender, EventArgs e)
{
statusTextBox.Text = "Output started.";
// Create the cancellation token source.
cts = new CancellationTokenSource();
try
{
// Create & start worker task.
await Task.Run(() => DoWork(cts.Token));
statusTextBox.Text = "Output ended.";
}
catch(OperationCanceledException ce)
{
// Note that we get "normal" exception handling
statusTextBox.Text = "Operation canceled.";
}
}
private void stopButton_Click(object sender, EventArgs e)
{
// Just cancel the source - nothing else required here
cts.Cancel();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10311 次 |
| 最近记录: |