我正在实现一个Parallel.ForEach循环来做一些工作,但是由于未处理的异常,我遇到了问题,虽然我认为我已经处理了取消。
为了试图找到问题所在,我在winform中制作了一个简单的测试设置。它有一个开始按钮,一个取消按钮和一个输出标签。
代码:
public partial class Form1 : Form
{
CancellationTokenSource cts = new CancellationTokenSource();
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
output.Text = "Running";
try
{
var runTask = Task<string>.Factory.StartNew(() => Run());
await runTask;
this.output.Text = runTask.Result;
}
catch(Exception ex)
{
throw ex;
}
}
private string Run()
{
int useThreads = Environment.ProcessorCount - 2 < 1 ? 1 : Environment.ProcessorCount - 2;
ParallelOptions options = new ParallelOptions() { MaxDegreeOfParallelism = useThreads, CancellationToken = cts.Token };
options.CancellationToken.Register(() => ActionOnCancel());
List<int> somelist =new List<int>();
for(int i = 0; i < 100; i++)
somelist.Add(i);
Parallel.ForEach(somelist, options, (row, loopstate) =>
{
if(loopstate.ShouldExitCurrentIteration || loopstate.IsExceptional)
loopstate.Stop();
Thread.Sleep(1000);
});
return "Done";
}
private void ActionOnCancel()
{
output.Text= "Cancelled";
}
private void button2_Click(object sender, EventArgs e)
{
cts.Cancel();
}
当我运行程序并点击取消按钮时(触发button2_Click事件),会一直出现以下错误:
“System.OperationCanceledException”异常在mscorlib.dll中发生,但未在用户代码中处理。
附加信息:操作已被取消。
如果有此异常的处理程序,则可以安全地继续运行程序。
调试器突出显示了Parallel.ForEach部分。但是为什么?我以为我通过CancellationToken正确处理了取消操作。
异常消息在“ex”中没有给我任何清晰度:“{"The operation was canceled."}”,嗯...是的...那就是我的意图......
我忽略了什么吗? 谢谢,
Matthijs