我有这种异步方法:
private static async Task Initializ( ) { /*Do Stuff Here*/ }
我希望能够监控调用此函数产生的任务:
Task T = Class.Initialize( );
if (T.IsCancelled){ /*Do Stuff Here*/ }
我已经找到CancellationTokenSource
。
如何让T
(或函数Initialize
)使用该源令牌,以便在取消时T.IsCancelled
为真?
我不确定,但我认为我的问题的答案在于使用TaskCompletionSource
对象。迈克给出的答案让我得出了这个结论......
答案 0 :(得分:3)
任务将在任何一个下的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*/
}