Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么取消父任务时未触发子任务的任务继续?_C#_.net_Task Parallel Library - Fatal编程技术网

C# 为什么取消父任务时未触发子任务的任务继续?

C# 为什么取消父任务时未触发子任务的任务继续?,c#,.net,task-parallel-library,C#,.net,Task Parallel Library,考虑以下C#代码: 子任务的继续不会触发,即B不会打印到控制台。注释掉取消呼叫将打印B 观察到: A C 期望 A B C 如果父任务被取消,子任务的继续似乎不会被触发,但我找不到这方面的文档。有没有人知道这里发生了什么/为什么,或者在哪里会有记录 编辑: 我忘了把取消令牌传给最后的续集。事实上,我发现文档内容如下 “[…]如果取消了先行项,将不会开始继续”,但是我被TaskContinuation.onlyonCancelled选项弄糊涂了。例如,这种情况是可能的 Cancellation

考虑以下C#代码:

子任务的继续不会触发,即B不会打印到控制台。注释掉取消呼叫将打印B

观察到:

A
C
期望

A
B
C
如果父任务被取消,子任务的继续似乎不会被触发,但我找不到这方面的文档。有没有人知道这里发生了什么/为什么,或者在哪里会有记录

编辑:

我忘了把取消令牌传给最后的续集。事实上,我发现文档内容如下 “[…]如果取消了先行项,将不会开始继续”,但是我被TaskContinuation.onlyonCancelled选项弄糊涂了。例如,这种情况是可能的

CancellationTokenSource tSource = new CancellationTokenSource();
Task tTest = Task.Factory.StartNew
        (
            () =>
            {
               throw new Exception("foobar");
            }, tSource.Token).ContinueWith(t =>
                 {
                    Console.WriteLine("A " + t.Status);
                  }
             , tSource.Token
             , TaskContinuationOptions.NotOnFaulted
             , TaskScheduler.Current
          )
          .ContinueWith
              (
                 t =>
                   {
                      Console.WriteLine("B " + t.Status);
                    }
                 , tSource.Token
               );

tTest.Wait();
Console.Read();

第一个延续设置为状态已取消(因为其TaskContinuationOptions值导致其不运行),而令牌未设置为已取消。所以最后一个继续在这里运行。

最终,如果子任务附加到其父任务,那么它依赖于它,并且由于您使用的是相同的取消令牌,因此您可以预期这种行为。您可以使用一个单独的取消令牌,但我认为您需要处理冒泡的取消异常,以保持流-另一个选项是分离任务


您可能需要查看和获取有关取消的文档。

现在我知道了。任务和嵌套任务中的代理立即开始。嵌套任务开始等待2000毫秒,但已超出检查取消令牌的时间点。嵌套任务中的2000毫秒等待导致继续取消,因为同时取消令牌。但是,父任务的继续没有取消令牌,因此它始终运行


编辑:关键是两个任务都使用相同的取消令牌。

t当您发送邮件时,您可以使用您的tcat twalk来避免将您的tcat twalk切换到您的键盘。我在文档中遗漏了“[…]如果先前的任务被取消,将不会开始继续。”。我对TaskContinuationOptions选项有点困惑。仅在取消时,我似乎无法想象取消antecent的场景,例如继续运行(antecent处于取消状态)。你是说功能上?从技术上讲,你几乎自己创造了一个场景。查看如果在创建令牌后立即取消该令牌会发生什么。
CancellationTokenSource tSource = new CancellationTokenSource();
Task tTest = Task.Factory.StartNew
        (
            () =>
            {
               throw new Exception("foobar");
            }, tSource.Token).ContinueWith(t =>
                 {
                    Console.WriteLine("A " + t.Status);
                  }
             , tSource.Token
             , TaskContinuationOptions.NotOnFaulted
             , TaskScheduler.Current
          )
          .ContinueWith
              (
                 t =>
                   {
                      Console.WriteLine("B " + t.Status);
                    }
                 , tSource.Token
               );

tTest.Wait();
Console.Read();