【问题标题】:How is continuation executed after await in WinForms/WPF?在 WinForms/WPF 中等待之后如何继续执行?
【发布时间】:2017-05-07 16:23:28
【问题描述】:

我试图优雅地放弃长时间运行的操作,这些操作本质上是一系列下载数据和更新 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语句中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...

【问题讨论】:

  • 继续返回消息循环。所以是的,可以在很短的时间内取消令牌

标签: c# wpf winforms asynchronous async-await


【解决方案1】:

Continuation 将异步运行,直到您的任务中第一次等待,然后它将返回到任务执行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多