2017-05-06 113 views
0

我想优雅地放弃长时间运行的操作,这些操作本质上就是下载数据和更新UI的顺序。在WinForms/WPF等待之后如何继续执行?

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

有一个blog post由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语句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... 
+1

继续被回送到消息循环。所以是的,有一个可以取消令牌的时间窗口 –

回答

0

将延续至第一的await异步运行你的任务里面,那么它将返回任务的执行。

相关问题