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 -> Cleanup -> Exit -> Cleanup -> ... また、最初の Cleanup は Task id 1 をパラメーターとして呼び出されます (これは直前に実行されたタスクですよね?)そして、このタスクのステータスはキャンセルされました(そして、タスクをどこでもキャンセルすることはありません)。
ここで何がうまくいかないのか誰にもわかりませんか?

編集: OK、msdn によると、継続の条件が満たされない場合、そのタスクはキャンセルされます。したがって、ErrorHandler はキャンセルされますが、完全なチェーンを停止するにはどうすればよいですか (または、キャンセルされたことをクリーンアップと終了で他の継続に通知します)。

4

2 に答える 2

0

ErrorHandler -> クリーンアップの継続を OnlyOnRanToCompletion または NotOnCanceled として設定すると機能します。また、非同期で物事を少し単純化できるかもしれません。このようなものはうまくいくかもしれません:

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

catch/finally ブロックで待機できないため、ここではエラー処理とクリーンアップが同期することに注意してください。変数に例外を格納するだけで、これを回避できます。後で null をチェックして、非同期エラー ハンドラに渡します。

于 2013-08-05T09:35:21.897 に答える