简体   繁体   English

在WinForms / WPF中等待后如何继续执行?

[英]How is continuation executed after await in WinForms/WPF?

I am trying to gracefully discard long running operations which are in the essence a sequence of downloading data and updating the UI. 我试图优雅地放弃长时间运行的操作,这些操作实质上是下载数据和更新UI的顺序。

For example user selects an item and its details start being loaded from the server. 例如,用户选择一个项目,然后从服务器开始加载其详细信息。 But then he changes his mind and selects another item. 但是随后他改变了主意,选择了另一个项目。 The previous operation is cancelled, and the process starts again. 先前的操作被取消,并且该过程再次开始。 Yet there is a possibility that data is already received and continuation is posted to the message loop for execution. 但是仍然有可能已经接收到数据并将继续发布到消息循环中以便执行。 The question is whether it is possible with async/await . 问题是async/await是否可能。

There is a blog post by Stephen Toub where he offers this extension: 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; 
}

In return statement return await task task is already completed. 在return语句中, return await task任务已经完成。
If I am awaiting a task in UI thread: 如果我在UI线程中等待任务:

var result = await task.WithCancellation(token);
...continuation...

The return await task; return await task; is executed in UI thread. 在UI线程中执行。

But does continuation run synchronously with continuation of awaited async method or is posted separately to the message loop? 但是,延续是否与等待的异步方法的continuation同步运行,还是单独发布到消息循环中?

Synchronous execution allows to avoid the situation when cancellation (user selects another item) occurs later than continuation appears in message queue. 同步执行可以避免在消息队列中出现取消(延迟时间)(用户选择其他项目)的情况之后。 If this is not the case, then I have to check additionally: 如果不是这种情况,那么我必须另外检查:

var result = await task.WithCancellation(token);
token.ThrowIfCancellationRequested();
...continuation...

继续将异步运行,直到任务内部第一次等待,然后将继续执行任务。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM