任务T.IsCancelled = false;我怎样才能做到这一点?

时间:2015-12-07 14:38:50

标签: c# wpf asynchronous desktop-application cancellationtokensource

我有这种异步方法:

private static async Task Initializ( ) { /*Do Stuff Here*/ }

我希望能够监控调用此函数产生的任务:

Task T = Class.Initialize( );
if (T.IsCancelled){ /*Do Stuff Here*/ }

我已经找到CancellationTokenSource

如何让T(或函数Initialize)使用该源令牌,以便在取消时T.IsCancelled为真?

修改

我不确定,但我认为我的问题的答案在于使用TaskCompletionSource对象。迈克给出的答案让我得出了这个结论......

4 个答案:

答案 0 :(得分:3)

来自the documentation

  

任务将在任何一个下的TaskStatus.Canceled状态下完成   以下条件:

     
      
  • 在此任务之前,CancellationToken已标记为取消   开始执行,

  •   
  • 该任务已确认其已经发出信号的取消请求   通过抛出一个承载的OperationCanceledException来取消   相同的CancellationToken。

  •   
  • 该任务已确认其已经发出信号的取消请求   通过调用ThrowIfCancellationRequested方法取消   在CancellationToken。

  •   

答案 1 :(得分:1)

更新:

使用此方法:

async Task<Task> UntilCompletionOrCancellation(Task asyncOp, CancellationToken ct)
{
   var tcs = new TaskCompletionSource<bool>(); 

   using(ct.Register(() => tcs.TrySetResult(true)))
       await Task.WhenAny(asyncOp, tcs.Task); 

   return asyncOp;
}

消费任务:

var cts = new CancellationTokenSource();

await UntilCompletionOrCancellation(Class.Initialize, cts.Token);

if (!Class.Initialize.IsCompleted)
{
    /*Do Stuff Here*/ 
}

另一种方法是从Initialize中删除异步

 private static Task Initialize()
 {
    var tcs = new TaskCompletionSource();

    //use TrySetResult or TrySetCancelled 

    return tcs.Task;
 }

您可以等待此任务并检查是否已取消或已完成。

答案 2 :(得分:0)

只需从异步方法中抛出OperationCanceledException即可。

以下内容将true写入控制台:

public static void Main()
{
    Console.WriteLine(DoSomethingAsync().IsCanceled);
}

private static async Task DoSomethingAsync()
{    
    throw new OperationCanceledException();
}

支持取消的一种更好的方法是让您的异步方法将CancellationToken作为参数,然后可以使用此标记来检查取消,例如:

public static async Task DoSomethingAsync(CancellationToken cancellationToken)
{    
    cancellationToken.ThrowIfCancellationRequested();
}

答案 3 :(得分:0)

您需要在方法中调用CancellationToken.ThrowIfCancellationRequested()并让异常冒泡。

CancellationTokenSource cts = new CancellationTokenSource();
Task T = Class.Initialize(cts.Token);
if (T.IsCancelled){ /*Do Stuff Here*/ }

private static async Task Initializ(CancellationToken token ) 
{
  /*Do Stuff Here*/ 
  token.ThrowIfCancellationRequested();
  /*Do More Stuff Here*/ 
}