我正在尝试优雅地丢弃长时间运行的操作,这些操作本质上是一系列下载数据和更新UI。
例如,用户选择一个项目,并开始从服务器加载其详细信息。但后来他改变了主意并选择了另一个项目。先前的操作被取消,并且该过程再次开始。然而,有可能已经接收到数据并且继续发布到消息循环以供执行。问题是是否可以使用async/await
。
Stephen Toub有一个blog post,他提供了这个扩展名:
public static async Task<T> WithCancellation<T>(
this Task<T> task, CancellationToken cancellationToken)
{
var tcs = new TaskCompletionSource<bool>();
using(cancellationToken.Register(
s => ((TaskCompletionSource<bool>)s).TrySetResult(true), tcs))
if (task != await Task.WhenAny(task, tcs.Task))
throw new OperationCanceledException(cancellationToken);
return await task;
}
返回语句return await task
任务已完成
如果我正在等待UI线程中的任务:
var result = await task.WithCancellation(token);
...continuation...
return await task;
在UI线程中执行。
但continuation
是否与等待异步方法的延续同步运行,还是单独发布到消息循环中?
同步执行允许避免在取消(用户选择另一个项目)发生在消息队列中出现延迟之后的情况。如果不是这样,那么我必须另外检查:
var result = await task.WithCancellation(token);
token.ThrowIfCancellationRequested();
...continuation...
答案 0 :(得分:0)
Continuation将异步运行,直到第一个等待你的任务,然后它将返回到任务执行。