加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – TPL继续任务:不确定谁是父任务

发布时间:2020-12-15 22:08:14 所属栏目:百科 来源:网络整理
导读:我有ContinuationOption.AttachedToParent标志的麻烦. 这是我的伪代码: Task parentTask = Task.Start(() = { Task childTask = Task.Start(() = doSomething(),ContinuationOption.AttachedToParent); childTask.ContinueWith(() = followingMethod(),Cont
我有ContinuationOption.AttachedToParent标志的麻烦.

这是我的伪代码:

Task parentTask = Task.Start(() =>   
   { 
        Task childTask = Task.Start(() => doSomething(),ContinuationOption.AttachedToParent);
        childTask.ContinueWith(() => followingMethod(),ContinuationOption.AttachedToParent);
   }

我知道如果“doSomething()”抛出并且异常childTask失败并且parentTask也因为失败而失败
ContinuationOption.AttachedToParent选项.

如果followingMethod()抛出异常,但parentTask状态为Completed,我会期望相同的行为.

我做错了还是继续任务的“父”任务不是我的“parentTask”?

解决方法

你的直觉是正确的,但我猜你最有可能只使用错误的API.

我知道它只是伪代码,但Task.Start()是一个实例方法,而不是一个静态方法,所以不会按照你指示的方式编译,我们不知道你是如何实际启动的任务,细节都很重要. TaskFactory.StartNew会做你想要的,但Task.Run不会.试试这个:

Task parent = Task.Factory.StartNew(() =>
{
  Task child = Task.Factory.StartNew(
     () => { Console.WriteLine("foo"); },TaskCreationOptions.AttachedToParent);
  Task continuation = child.ContinueWith(
     (Task prev) => { throw new InvalidOperationException("Test"); },TaskContinuationOptions.AttachedToParent);
});
try
{
  parent.Wait();
}
catch (AggregateException ex)
{
  if (ex.Flatten().InnerException is InvalidOperationException)
  { 
    Console.WriteLine("The continuation exception was propagated to parent");
  }
}

如果你改变了

Task parent = Task.Factory.StartNew(...)

Task parent = Task.Run(...)

然后你不会得到你想要的行为,因为Task.Run本质上是TaskFactory.StartNew的包装器,其中(除其他外)指定了TaskCreationOptions.DenyChildAttach,因此两个嵌套任务都将分离运行(没有父项).我猜这就是你的问题所在.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读