[解決済み] prevTask.Wait()はContinueWith(Tasksライブラリ)と併用することが推奨されていますか?
質問
最近、私が使っていたタスクの.ContinueWithの使い方が適切でないと言われました。インターネット上でその証拠をまだ見つけていないので、皆さんに質問して、答えが何であるか見てみようと思います。以下は、私が.ContinueWithをどのように使用しているかの一例です。
public Task DoSomething()
{
return Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 2");
})
.ContinueWith((prevTask) =>
{
Console.WriteLine("Step 3");
});
}
これは単純な例で、非常に高速に実行されることは分かっていますが、各タスクが何らかの長い処理を行うと仮定してください。そこで、私が言われたのは、.ContinueWithの中で、prevTask.Wait()と言う必要があり、さもなければ、前のタスクが終了する前に仕事をすることができるということです。そんなことが可能なのでしょうか?私は、2つ目のタスクと3つ目のタスクは、前のタスクが終了した後にのみ実行されると仮定しています。
コードの書き方を教えてもらったこと。
public Task DoSomething()
{
return Task.Factory.StartNew(() =>
{
Console.WriteLine("Step 1");
})
.ContinueWith((prevTask) =>
{
prevTask.Wait();
Console.WriteLine("Step 2");
})
.ContinueWith((prevTask) =>
{
prevTask.Wait();
Console.WriteLine("Step 3");
});
}
どのように解決するのですか?
えーっ...。現在の回答のいくつかは何かが欠けていると思います。例外が発生した場合はどうなるのでしょうか?
を呼び出す唯一の理由は
Wait
を呼び出す唯一の理由は、先行詞から例外が発生する可能性があることを 継続の中で観察するためでしょう。同じことが
Result
の場合
Task<T>
にアクセスした場合、また、手動で
Exception
プロパティに手動でアクセスした場合も同様です。
正直なところ、私なら
Wait
を呼び出したり
Result
にアクセスするのは、例外が発生した場合にそれを再レイズする代償を支払うことになり、不必要なオーバーヘッドになるからです。その代わり、単に
IsFaulted
プロパティをチェックすればいいのです。
Task
. また、成功か失敗のどちらかに基づいてのみ起動する複数の兄弟継続をチェーンすることで、 フォークされたワークフローを作成することもできます。
TaskContinuationOptions.OnlyOnRanToCompletion
と
TaskContinuationOptions.OnlyOnFaulted
.
さて、継続の際に先行詞の例外を観察する必要はありませんが、例えば "ステップ 1" が失敗した場合、ワークフローを先に進ませたくない場合があります。そのような場合: 指定した
TaskContinuationOptions.NotOnFaulted
を指定します。
ContinueWith
を呼び出すと、継続ロジックが起動することさえできなくなります。
もし、あなた自身の継続が例外を観察しないなら、このワークフロー全体の完了を待っている人がそれを観察することになる、ということを心に留めておいてください。彼らは
Wait
を実行中であるか
Task
を使うか、自分自身の継続が完了したことを知るために、自分自身の 継続を付け足したか、どちらかです。もし後者であれば、その継続は前述の観測ロジックを使用する必要があります。
関連
-
[解決済み】GDI+、JPEG画像をMemoryStreamに変換する際にジェネリックエラーが発生しました。
-
[解決済み】プログラム実行中に1秒待つ
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み] 'IEnumerable<SelectListItem>' 型の ViewData アイテムで、キーが国であるものは存在しない。
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
-
[解決済み】C#のyieldキーワードは何に使われるのか?
-
[解決済み】複数のタスクを待機させ、異なる結果を得ることができる。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] エンティティタイプ ApplicationUser は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】スクリプトクラスが見つからないので、スクリプトコンポーネントを追加できない?
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み】統合マネージドパイプラインモードで適用されないASP.NETの設定が検出された
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み】Visual studio 2019がデバッグ時にフリーズする件
-
[解決済み】画像のペイントにTextureBrushを使用する方法
-
[解決済み】「namespace」なのに「type」のように使われる。
-
[解決済み】WebResource.axdとは何ですか?