所以, task.Wait()
可以转化为 await task
。当然,语义是不同的,但这大致是我将如何转换阻塞代码 Waits
用异步代码 awaits
。
我的问题是如何改造 task.Wait(CancellationToken)
各自的 await
声明?
所以, task.Wait()
可以转化为 await task
。当然,语义是不同的,但这大致是我将如何转换阻塞代码 Waits
用异步代码 awaits
。
我的问题是如何改造 task.Wait(CancellationToken)
各自的 await
声明?
创建一个新的 Task
表示现有任务但具有额外的取消令牌非常简单。你只需要打电话 ContinueWith
在任务上,使用新标记,并在延续体中传播结果/异常。
public static Task WithCancellation(this Task task,
CancellationToken token)
{
return task.ContinueWith(t => t.GetAwaiter().GetResult(), token);
}
public static Task<T> WithCancellation<T>(this Task<T> task,
CancellationToken token)
{
return task.ContinueWith(t => t.GetAwaiter().GetResult(), token);
}
这允许你写 task.WithCancellation(cancellationToken)
将令牌添加到任务,然后您可以 await
。
await
用于异步方法/委托,它们接受一个 CancellationToken
所以当你打电话时你应该通过一个(即 await Task.Delay(1000, cancellationToken)
),或者他们没有,他们不能真正取消(例如等待I / O结果)。
但是,您可以使用此扩展方法放弃*这些类型的任务:
public static Task<T> WithCancellation<T>(this Task<T> task, CancellationToken cancellationToken)
{
return task.IsCompleted // fast-path optimization
? task
: task.ContinueWith(
completedTask => completedTask.GetAwaiter().GetResult(),
cancellationToken,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
}
用法:
await task.WithCancellation(cancellationToken);
*被放弃的任务不会被取消,但您的代码表现得像是一样。它要么以结果/异常结束,要么永远保持活力。