[解決済み] プロミス型タスクでStartを呼び出してはいけない。
質問
シンプルなwpfのデスクトップアプリケーションを作成しています。UIは、ボタンと.csファイルのコードだけを持っています。
private void Button_Click_2(object sender, RoutedEventArgs e)
{
FunctionA();
}
public void FunctionA()
{
Task.Delay(5000).Start();
MessageBox.Show("Waiting Complete");
}
しかし、驚くべきことに、この行は
Task.Delay(5000).Start();
を投げています。
InvalidOperationException
:
Start は、プロミス形式のタスクでは呼び出されない場合があります。
なぜこのような状態になるのか、どなたか教えていただけませんか?
解決方法は?
このエラーが発生するのは
Task
クラスは、あなたに渡す前にすでにタスクを開始しています。 を呼び出すのは
Start
は、コンストラクタを呼び出して作成したタスクで、タスクを作成したときに開始させないというやむを得ない理由がない限り、そうすべきではないでしょう。
Task.Run
または
Task.Factory.StartNew
を作成し、新しい
Task
.
これで、あの厄介な
Start
. コードを実行すると、メッセージボックスが5秒後ではなく、すぐに表示されることがわかりますが、これはどうしたことでしょう?
さて。
Task.Delay
は、5秒後に完了するタスクを与えるだけです。 スレッドの実行を5秒間停止させるわけではありません。 やりたいことは、そのタスクが終了した後に実行されるコードを用意することです。 それが
ContinueWith
はそのためのものです。 これは、与えられたタスクが完了した後に、いくつかのコードを実行することができます。
public void FunctionA()
{
Task.Delay(5000)
.ContinueWith(t =>
{
MessageBox.Show("Waiting Complete");
});
}
これは期待通りの動作になります。
また、C# 5.0の
await
キーワードを使用すると、より簡単に連続性を追加することができます。
public async Task FunctionA()
{
await Task.Delay(5000);
MessageBox.Show("Waiting Complete");
}
ここで起こっていることの完全な説明はこの質問の範囲を超えていますが、最終的には前のメソッドと非常に似た振る舞いをするメソッドになります。メソッドを呼び出した5秒後にメッセージボックスが表示されますが、メソッド自体はどちらの場合も[ほとんど]すぐに返されます。 とはいえ
await
は非常に強力で、一見シンプルで簡単そうに見えるメソッドでも
ContinueWith
を直接使用します。 また、エラー処理も大幅に簡素化され、多くの定型的なコードを削除することができます。
関連
-
[解決済み】コレクションが変更され、列挙操作が実行されないことがある。
-
[解決済み】エラー。「戻り値を変更できません」 C#
-
[解決済み】指定されたキャストが有効でない?
-
[解決済み】なぜこのコードはInvalidOperationExceptionを投げるのですか?
-
[解決済み] UnityでOnCollisionEnterが呼ばれない
-
[解決済み] 2つのリストを結合する
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】「namespace」なのに「type」のように使われる。
-
[解決済み] Moqでメソッドが呼び出されていないことを確認する方法は?
-
[解決済み] xからyへの共変数配列変換で実行時例外が発生することがある
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】「未割り当てのローカル変数を使用」とはどういう意味ですか?
-
[解決済み】Excel "外部テーブルが期待された形式ではありません。"
-
[解決済み】パディングが無効で、削除できない?
-
[解決済み】トランスポート接続からデータを読み取れない:既存の接続は、リモートホストによって強制的に閉じられました。
-
[解決済み】Socket.Selectがエラー "An operation was attempted on something that is not a socket" を返す。
-
[解決済み】ランダムなブーリアンを生成する最速の方法
-
[解決済み] 2つのリストを結合する
-
[解決済み】画像のペイントにTextureBrushを使用する方法
-
[解決済み】「namespace」なのに「type」のように使われる。
-
[解決済み】Task.Start/WaitとAsync/Awaitの違いは何ですか?