如何将task.Wait(CancellationToken)转换为await语句?
因此, task.Wait()
可以转换为await task
。 当然,语义是不同的,但这大致是我将使用Waits
将阻塞代码转换为具有Waits
的异步代码的方式。
我的问题是如何将task.Wait(CancellationToken)
转换为相应的await
语句?
创建一个代表现有任务但具有额外取消令牌的新Task
非常简单。 您只需要在任务上调用ContinueWith
,使用新标记,并在连续体中传播结果/exception。
public static Task WithCancellation(this Task task, CancellationToken token) { return task.ContinueWith(t => t.GetAwaiter().GetResult(), token); } public static Task WithCancellation (this Task 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 WithCancellation (this Task 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);
*被放弃的任务不会被取消,但您的代码表现得像是一样。 它要么以结果/exception结束,要么永远保持活力。