1

我有这个异步方法:

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

4 回答 4

3

文档

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

  • 在任务开始执行之前,它的 CancellationToken 被标记为取消,

  • 该任务通过抛出具有相同 CancellationToken 的 OperationCanceledException 来确认其已发出信号的 CancellationToken 的取消请求。

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

于 2015-12-07T14:45:38.670 回答
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 中删除 async

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

    //use TrySetResult or TrySetCancelled 

    return tcs.Task;
 }

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

于 2015-12-07T14:51:09.303 回答
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*/ 
}
于 2015-12-07T14:46:05.403 回答
0

OperationCanceledException从您的异步方法中抛出一个就足够了。

以下写入true控制台:

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

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

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

public static async Task DoSomethingAsync(CancellationToken cancellationToken)
{    
    cancellationToken.ThrowIfCancellationRequested();
}
于 2015-12-07T14:45:18.233 回答