在Winforms/WPF中等待后,如何执行延续



我试图优雅地丢弃长期运行的操作,这些操作本质上是下载数据和更新UI的顺序。

例如,用户选择一个项目及其详细信息从服务器加载。但是随后他改变了主意,选择了另一个项目。以前的操作被取消,并且该过程再次开始。然而,有可能已经收到数据,并将延续发布到消息循环中以进行执行。问题是async/await是否可能。

Stephen Toub有一篇博客文章,他提供了此扩展名:

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...

延续将异步运行,直到任务中的第一个等待,然后它将返回任务执行。

最新更新