私は特定のユースケースで動作するようにC#でタスクを取得しようとしていますが、タスクの継続オプションがタスクの流れに与える影響を理解していません。取り消し自体を起動せずに取り消されたタスクを処理するには?
私がやっていることは、ContinueWithと連鎖している一連の作業を取得することです。 - > B - > C - > D
しかし、私はイベントで短絡するオプションこのエラーを含めたいので、それは次のようになります
A:これは、このようになります。 :
A - > B - > C - > D - > X
だから私はContinueWith機能のそれぞれのタスク継続オプションとして "OnlyOnRanToCompletion" を置きます。次に、取り消しをキャッチしてエラーを返すために、タスクの継続オプションを「OnlyOnCanceled」に設定してチェーンの最後に最終タスクを配置します。
問題は、この最後のブロックがヒットした場合、継続オプションが満たされず、元の一連のタスクが決してキャンセルされなかった場合でもタスクがキャンセルされるように設定されることです。
AからDが実行され、そのうちの1つがキャンセルされた場合は残りをスキップしてXを実行します。AからDが完了すると、タスクはキャンセルされません。解決策は、任意の数の継続をサポートする必要があり、LINQ.Expressionsを使用して作成されるため、async/awaitを使用することは、創造的に行われていない限り、おそらく飛ぶことはありません。
これを示すいくつかのサンプルコードは次のとおりです。
var cts = new CancellationTokenSource();
var token = cts.Token;
var t = Task.FromResult(1)
.ContinueWith(
x => x.Result + 1,
token,
TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default)
.ContinueWith(
x => x.Result + 1,
token,
TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.Default)
.ContinueWith(
x => -1,
token,
TaskContinuationOptions.OnlyOnCanceled,
TaskScheduler.Default);
ここで予想される動作は、3を返すようになり、ステータスが完了していません。
実際には、タスクがキャンセルされます。
どうすればよいですか?
また、私は、LINQ.Expressionsからコンパイルされたものの中でTPLをピギーバックし、例外を投げずに非同期で評価し、最後にエラーを処理できるようにすることを目標にしているため、私はasync
を使用できません。
非同期ワークフローを構築するには、「ContinueWIth」ではなく、実際には「await」を使用する必要があります。 'await'は使用するのがずっと簡単であり、多くの分野、特にここで見ているように、エラー処理に関しては、より望ましいデフォルト動作があります。 – Servy
私はこれを質問に加えるべきです - 私ができたら、私はできますが、できません。私は非同期に実行する必要がある小さなプログラムをコンパイルするためにLINQ.Expressionsを使用していますが、そのアクセス権はありません。 –
私は強く疑いますが、実際の問題に関する十分な情報を提供しない場合、人々はあなたに良い解決策を与えることはできません。 – Servy