如何从另一个任务取消任务?

时间:2017-09-30 08:26:49

标签: c# task cancellationtokensource

try{
      var cts = new CancellationTokenSource();
      CancellationToken ct = cts.Token;
      Task.Run(()=>
      {
          //DoSomething(); excute long time   
      }, ct);
      Task.Run(()=>
      {
          Thread.Sleep(1000);
          cts.Cancel();
      }, ct).Wait();
}
catch (OperationCanceledException ex)
{
      Console.WriteLine("exception" + ex.Message);
}
finally
{
      Console.WriteLine("finally");
}

当我致电cts.Cancel()

DoSomething仍在工作.....................

我怎么能先停止任务?

如果DoSomething有循环

我可以添加ct.ThrowIfCancellationRequested(),它正在运作

但DoSomething不是循环,我该怎么办?

1 个答案:

答案 0 :(得分:1)

DoSomething()是否为循环,它必须显式检查并响应取消令牌上的IsCancellationRequested属性。如果此属性为true,则函数必须尽快返回,即使这意味着未完成完整执行。请注意,DoSomething()不是循环。

void DoSomething(System.Threading.CancellationToken tok)
{
    Thread.Sleep(900);
    if (tok.IsCancellationRequested)
        return;
    Console.WriteLine("after 1");
    Thread.Sleep(1800);
    if (tok.IsCancellationRequested)
        return;
    Console.WriteLine("after 2");

}
void Main()
{
    try
    {
        var cts = new CancellationTokenSource();
        CancellationToken ct = cts.Token;
        System.Threading.Tasks.Task.Run(() =>
        {
           DoSomething(ct);
          //DoSomething(); excute long time   
      });
        System.Threading.Tasks.Task.Run(() =>
        {
            Thread.Sleep(1000);
           cts.Cancel();
        }).Wait();
    }
    catch (OperationCanceledException ex)
    {
        Console.WriteLine("exception" + ex.Message);
    }
    finally
    {
        Console.WriteLine("finally");
    }
}

注意:DoSomething()必须引用取消令牌并显式检查IsCancellationRequested属性。取消令牌在Task.Run()中的作用在这个答案中解释:https://stackoverflow.com/a/3713113/41410,但它没有发挥作用正在取消DoSomething()的流程