【发布时间】:2015-02-17 14:47:30
【问题描述】:
我正在尝试了解 .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。
【问题讨论】:
-
Faulted是这里的特殊状态,其中(无论出于何种原因)孩子的状态反映在父母身上。Cancelled特别是 called out 为“要以取消状态结束,任务必须在开始执行之前请求取消,或者必须在执行期间确认取消请求。”并且这些都不适用于父母。 -
所以父任务应该等待子任务,并抛出它自己的
OperationCanceledException以取消其状态?