2013-08-03 96 views
1

我用條件延續構建了一個小型任務鏈,但是我遇到了一些有害的行爲。 我的鏈條是這樣的:任務繼續奇怪的行爲

LoadSettings (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
CheckForUpdates (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
Update (OnlyOnFaulted)-> ErrorHandler (none)-> Cleanup (none)-> Exit 
| (OnlyOnRanToCompletion) 
Cleanup (OnlyOnFaulted)-> ErrorHandler (none)-> Exit 
| (OnlyOnRanToCompletion) 
Exit 

當我明白這個鏈應該異步地運行(即不是在UI線程),但一個又一個的(所以LoadSettings - > CheckForUpdates - > ...)。
然而,我得到這種行爲:
LoadSettings - > CheckForUpdates - >清理 - >退出 - >清理 - > ... 此外,第一個清理被調用與任務id 1作爲參數(這是任務執行權之前,對嗎?),並且此任務的狀態爲已取消(並且我從不在任何地方取消任務)。
有誰知道這裏發生了什麼問題?

編輯:好吧,根據msdn,如果延續條件不滿足,它的任務會被取消。所以ErrorHandler被取消了,但是我怎樣才能停止整個鏈(或者通過清理和退出來通知其他的繼續它已經被取消)?

回答

0

使用Task.WhenAny您可以創建一個任務,該任務在成功處理程序或錯誤處理程序完成時運行。關閉該任務,您將繼續使用Cleanup

有時很難建立正確的連續鏈,但你可以使用組合函數構造相當複雜的流圖,如Task.WhenAny

如果你可以使用異步/等待任務簡化了很多。然後您可以使用正常的控制流程結構。你也可以使用迭代器模擬await。

0

設置ErrorHandler - >清理延續,因爲OnlyOnRanToCompletion或NotOnCanceled可以工作。另外,也許你可以用async簡化一些事情。像這樣的東西可以工作:

try { 
    var settings = await LoadSettings(); 
    var updatesNeeded = await CheckForUpdates(settings); 
    await Update(updatesNeeded); 
} catch (Exception e) { 
    ErrorHandler(e); 
} finally { 
    Cleanup(); 
} 

注意,錯誤處理和清理工作將同步在這裏,因爲你不能在catch等待/ finally塊。您只需將該異常存儲在一個變量中即可解決該問題,您稍後將檢查該變量並將其傳遞給異步錯誤處理程序。