2017-05-06 63 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異步運行你的任務裏面,那麼它將返回任務的執行。

相關問題