gpt4 book ai didi

c# - 子任务取消,父任务完成?

转载 作者:太空狗 更新时间:2023-10-29 21:39:02 26 4
gpt4 key购买 nike

我试图了解 .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,即使两个任务共享 token ,并附加子项。

如何让父任务在发生取消时返回状态 Canceled

注意如果我抛出异常,两个任务都会返回 Faulted

最佳答案

这是 MSDN 上规定的预期行为。父任务必须 wait (向下滚动到取消部分)子任务。父任务必须处理所有良性故障(如取消)。

要使您的父任务失败,只需等待并传递 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);

// This is the magic line.
child.Wait(token);
}, token);

如果您使用这段代码来做一些有成效的事情,而不仅仅是为了测试,您还应该考虑使用支持 async 委托(delegate)的简化的 Task.Run() Task.Factory.StartNew()。这article很有趣。

关于c# - 子任务取消,父任务完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28564074/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com