2017-10-27 4 views
1

私は呼びたい3つの機能を持っています - void DoJob1()void DoJob2()とCleanup()。 DoJob()は、DoJob()が成功した場合にのみ実行する必要があります。クリーンアップは常に呼び出されるべきです。C#3 Semi-Dependent Tasksを実行しています

私は、次の使用してこの作業を取得しようとしている:

Task theTask = new Task(() => DoJob1(), CancelTokenSource.Token); 
theTask.ContinueWith(currTask => DoJob2(), 
    TaskContinuationOptions.OnlyOnRanToCompletion | 
    TaskContinuationOptions.AttachedToParent); 
theTask.ContinueWith(currTask => Cleanup()); 

DoJob2は正しくDoJob1後に実行されますが、クリーンアップは、このように同時に実行されます。私はなぜそれを止めてどちらかが失敗した場合でも常に正しく実行されるようにする簡単な方法は何も見えないのですか?

答えて

1

DoJob2はDoJob1の後で正常に実行されますが、これと同時にクリーンアップが実行されます。

これは、theTask(DoJob1を実行中)が成功するとすぐに処理を続けるように指示しているからです。 theTaskDoJob2の完了を指すように変更することができます。

Task theTask = new Task(() => DoJob1(), CancelTokenSource.Token); 
theTask = theTask.ContinueWith(currTask => DoJob2(), 
    TaskContinuationOptions.OnlyOnRanToCompletion | 
    TaskContinuationOptions.AttachedToParent); 
theTask.ContinueWith(currTask => Cleanup()); 

それとも、インライン構文を使用することができます、あなたが与えてくれたの例から、当然のことながら

try 
{ 
    await Task.Run(() => DoJob1()); 
    await Task.Run(() => DoJob2()); 
} 
finally 
{ 
    await Task.Run(() => CleanUp()); 
} 

Task theTask = new Task(() => DoJob1(), CancelTokenSource.Token) 
    .ContinueWith(currTask => DoJob2(), 
     TaskContinuationOptions.OnlyOnRanToCompletion | 
     TaskContinuationOptions.AttachedToParent) 
    .ContinueWith(currTask => Cleanup()); 

可能ならば、あなたもasync/await構文を使用して検討するかもしれません非同期コードがないと思われるので、Taskを使用している理由を理解するのは難しいです。たぶん、あなたは物事を単純化することができます。そのため

try 
{ 
    DoJob1(); 
    DoJob2(); 
} 
finally 
{ 
    CleanUp(); 
} 
+0

おかげで - 私はそれをやってみますよ。実際のコードは非同期コードを持っていますが、簡単に記述できるように基本を簡略化しました。 – Boycey

関連する問題