在任务完成之前,取消异步方法不起作用

时间:2017-12-28 20:49:52

标签: c# asynchronous cancellationtokensource

我有一个异步方法。我无权访问Frame.Execute()代码方法。

问题:在Frame.Execute完成执行之前,myTask不会取消。

我需要在请求取消时立即取消Frame.Execute()和myTask。

private async Task myTask(CancellationToken tkn)
{
tkn.ThrowIfCancellationRequested();
var myList=  await Task.Run(()=> Frame.Execute(),tkn);

//Do other things
}

3 个答案:

答案 0 :(得分:0)

您收到CancellationToken作为输入参数的事实通常意味着令牌由外部代码控制。因此,您编写的代码段会暴露以下假设:

  1. 一个任务是由外部代码创建的,你的第一行(ThrowIfCancellationRequested)是绝对合法的 - 如果令牌处于“取消”状态,你的代码就会在这里停止任务。
  2. 如果到目前为止没有取消,你的任务会运行一个新的任务(子任务),它接收与输入参数相同的令牌,这绝对是合法的 - 所以一旦发出信号,令牌就可以终止两个任务的整个子树。
  3. @pmcilreavy评论中提到的唯一错误的事情是子任务代码也应检查令牌状态。否则,这里没有取消,抱歉。

    P.S。您可能会发现此MSDN链接很有用:https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-cancel-a-task-and-its-children

答案 1 :(得分:0)

Frame.Execute似乎与我发布的内容完全不同。您正在做的是在新任务中启动同步过程。您传递的取消令牌仅与您已创建的任务相关,但Frame.Execute方法未通过取消令牌并且不会注意它。它很可能没有一个接受一个的重载,因为它似乎不是异步的。所以一旦Frame.Execute开始它就不会返回,直到它完成此时你创建的任务得到控制权然后它会注意你取消的令牌

答案 2 :(得分:0)

嗨试试这个,在调用Frame.Execute()代码方法之后写下ThrowIfCancellationRequested,并且在调用myTask之后不要在taks调用中发送取消令牌,而不是使用cancellationTokenSource.Cancel(),查看下一个示例代码。

using System;
using System.Threading;
using System.Threading.Tasks;

CancellationTokenSource cancellationTokenSource =
new CancellationTokenSource();

CancellationToken tkn = cancellationTokenSource.Token;

private async Task myTask(CancellationToken tkn)
{
    Console.WriteLine("Hi now i'm inside the Task");    
    var IsOut =  await Task.Run(()=> {
        while(true)
                {
                    Console.Write("*");
                    Thread.Sleep(500);
                }
        return true;
        });
    tkn.ThrowIfCancellationRequested();
    Console.WriteLine("This code not execute");
//Do other things
}

Console.WriteLine("Before to invoke the Taks");
Task.Run(()=> myTask(tkn));
Thread.Sleep(3000);
cancellationTokenSource.Cancel();
Console.WriteLine("");
Console.WriteLine("The End ");