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
直接使用して作成するのははるかに難しく、面倒です。また、エラー処理の処理が大幅に簡素化され、多くの定型コードが削除されます。