当子任务之一引发异常时,取消子任务 [英] Cancel child tasks when one of them throws an exception
本文介绍了当子任务之一引发异常时,取消子任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想改进以下代码以添加取消支持.基本上,一旦孩子抛出异常,我需要取消所有孩子以及父任务.我写了下面的代码作为学习经验.我只能在所有孩子都完成后才能看到AggregateException
,但是我不希望那样.
I'd like to improve the following code to add cancellation support. Basically, what I need to do is cancel all children as well as the parent task once a child throws an exception. I wrote the below code as a learning experience. I can see AggregateException
only after all children finish, but I don't want that.
static int GetSum()
{
var parent = Task<int>.Factory.StartNew(() =>
{
var children = new Task<int>[100];
for (var i = 0; i < children.Length; i++)
{
var index = i;
children[index] = Task<int>.Factory.StartNew(() =>
{
var randomNumber = new Random().Next(5);
if (randomNumber == 0)
{
throw new Exception();
}
return randomNumber;
}, TaskCreationOptions.AttachedToParent);
}
Task.WaitAll();
Console.WriteLine("Children finished");
return children.Sum(t => t.Result);
});
parent.Wait();
Console.WriteLine("Parent finished");
return parent.Result;
}
我不知道如何使用以下内容:
I believe I need to use the following though I don't know how:
var source = new CancellationTokenSource();
var token = source.Token;
推荐答案
you can just use Task.WaitAny
instead of WaitAll and make a cancel request to the token once an AgregateException was thrown something like this
static int GetSum()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var parent = Task<int>.Factory.StartNew(() =>
{
var children = new Task<int>[100];
for (var i = 0; i < children.Length; i++)
{
var index = i;
children[index] = Task<int>.Factory.StartNew(() =>
{
for (int j = 0; j < 100000; j++)
{
if (!token.IsCancellationRequested)
{
var randomNumber = new Random().Next(5);
if (randomNumber == 0)
{
throw new Exception();
}
return randomNumber;
}
else
{
token.ThrowIfCancellationRequested();
}
}
return 0;
}
, token);
}
try
{
Task.WaitAny(children);
}
catch (AggregateException ae)
{
tokenSource.Cancel();
ae.Handle((task) =>
{
Console.WriteLine("Cancel all others child tasks requested ");
return true;
});
}
Console.WriteLine("Children finished");
return children.Sum(t => t.Result);
});
try
{
parent.Wait();
}
catch (AggregateException aex)
{
aex.Handle((task) =>
{
Console.WriteLine("Cancel child work done ");
return true;
});
}
Console.WriteLine("Parent finished");
return parent.Result;
}
这篇关于当子任务之一引发异常时,取消子任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文