2011-02-07 42 views
6

我有一個問題,可以使用什麼機制來取消正在進行的異步操作,而不是異步/等待上下文中的取消令牌。我確信這是一個考慮到語言的命令性質的充分研究的設計決定,但在實際情況下,必須將取消對象傳遞給所有異步方法,至少有點痛苦。還有另一個來自C#社區的設計思路,或者建議的取消機制是否正確?我想我錯過了一些東西。異步/等待取消機制

+0

使用取消令牌的取消機制似乎是事情發展的方向,包括在C#5的異步CTP中。 http://msdn.microsoft.com/en-us/vstudio/gg316360。這不是叫C#5,但我在這裏用它來表示C#的「下一個」版本。 – 2011-02-07 21:29:31

回答

4

取消令牌是最佳實踐,尤其是當異步過程昂貴,沒有預設結束條件或涉及外部資源時。

但是,如果您願意,您可以簡單地「放棄」。而不是告訴異步線程放棄處理和清理,只是「超時」;停止等待它完成,分離任何聽衆,並繼續運行。當線程最終完成時,它會檢查它的事件,意識到沒有人在聽,並且靜靜地終止。好處是簡單,但有其中這將是一件壞事,很多情況下:

  • 如果除非你告訴它停止異步進程將繼續處理永遠,它會繼續在後臺運行,搭售啓動CPU和其他資源,直到應用程序關閉,此時線程將被終止。
  • 如果異步線程正在執行一個可中止的,可逆的工作單元,例如數據庫操作,如果用戶按下取消,他們預期到目前爲止所做的任何事情都已被回滾。如果你停止傾聽並繼續前進,他們會得到的是他們認爲他們取消了的事情。
  • 在大多數情況下,異步操作涉及需要時間處理的外部資源,並且還需要進行適當的清理。網絡套接字必須斷開連接,數據庫連接關閉,文件解鎖等。儘管放棄意味着你不必處理這些事情,而是讓線程正常結束,但普通的用戶體驗是讓用戶感到厭煩,打取消然後重試該操作。這意味着您在之前的異步操作中使用的資源必須發佈才能再次使用它。
1

爲了異步操作的取消是有道理的,該操作必須執行謹慎的步驟,因爲它是由操作檢查取消標記和持續自行停止。即取消標記僅僅是要實現的模式而不是異步/等待的機制。

這意味着如果你的異步操作只是一個帶有完成句柄的I/O調用,那麼你可以放棄而不是取消,因爲操作不會有oppurtunity來檢查你的令牌直到那個電話回來了,沒有什麼可以獲得的。因此,當考慮取消令牌時,首先考慮是否可以通過支持取消或者是否只是不等待它完成(即使用超時機制)來更有效地進行該操作。