use*_*122 4 c# exception cancellation parallel.foreach
我正在实现一个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();
}
Run Code Online (Sandbox Code Playgroud)
当我运行程序并点击取消按钮(触发button2_Click)时,我继续收到此错误:
mscorlib.dll中出现"System.OperationCanceledException"类型的异常,但未在用户代码中处理
附加信息:操作已取消.
如果存在此异常的处理程序,则可以安全地继续该程序.
调试器突出显示Parallel.ForEach部分.但为什么???我以为我通过CancellationToken处理了取消更正.
ex中的异常消息并没有给我任何清晰的说明:"{"操作被取消了."}"呃......是啊....这是意图......
我在俯瞰什么?问候,
Matthijs
始终抛出此异常.如果在CancellationTokenSource上调用cancel方法,则在访问Parallel Tasks时必须处理OperationCanceledException.
try
{
Parallel.ForEach(somelist, options, (row, loopstate) =>
{
if(loopstate.ShouldExitCurrentIteration || loopstate.IsExceptional)
loopstate.Stop();
Thread.Sleep(1000);
});
}
catch (OperationCanceledException)
{
// Handle the cancelled Task
}
Run Code Online (Sandbox Code Playgroud)
CancellationToken.Register() 提供了一种向取消添加回调的方法,但不会根据 OperationCanceledException 来“处理”它。
我建议您也在 Run() 方法中放置一个 try/catch 块。
归档时间: |
|
查看次数: |
9476 次 |
最近记录: |