当附加孩子时,我试图了解.net任务的行为。
我有以下测试代码:
void Test()
{
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
Task child = null;
var parent = Task.Factory.StartNew(() =>
{
child = Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested)
Thread.Sleep(100);
token.ThrowIfCancellationRequested();
}, token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
}, token);
Thread.Sleep(500);
Debug.WriteLine("State of parent before cancel is {0}", parent.Status);
Debug.WriteLine("State of child before cancel is {0}", child.Status);
tokenSource.Cancel();
Thread.Sleep(500);
Debug.WriteLine("State of parent is {0}", parent.Status);
Debug.WriteLine("State of child is {0}", child.Status);
}
结果是:
State of parent before cancel is WaitingForChildrenToComplete
State of child before cancel is Running
A first chance exception of type 'System.OperationCanceledException' occurred in mscorlib.dll
State of parent is RanToCompletion
State of child is Canceled
显然,父任务状态不是Canceled
,即使两个任务共享令牌并且已附加子任务。
Canceled
取消发生后如何使父任务返回状态?
注意如果我抛出异常,则两个任务都将返回Faulted
。
如MSDN上所述,这是预期的行为。父任务必须等待(向下滚动到取消部分)子任务。父任务必须处理所有良性故障(例如取消)。
要使您的父任务失败,只需等待并传递令牌:
Task child = null;
var parent = Task.Factory.StartNew(() =>
{
child = Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested) Thread.Sleep(100);
token.ThrowIfCancellationRequested();
}, token, TaskCreationOptions.AttachedToParent, TaskScheduler.Default);
// This is the magic line.
child.Wait(token);
}, token);
如果您要使用此代码来做一些富有成效的工作,而不仅仅是为了进行测试,则还应该考虑使用简化的Task.Run()
支持async
委托,而不是Task.Factory.StartNew()
。这篇文章非常有趣。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句