私は多くの記事を読みましたが、まだこの部分を理解できません。
このコードを検討してください:
private async void button1_Click(object sender, EventArgs e)
{
await Dosomething();
}
private async Task<string> Dosomething()
{
await Task.Run((() => "Do Work"));
return "I am done";
}
最初の質問:
ボタンをクリックすると、DoSomethingが呼び出され、Task.Run(間違っていない場合)を呼び出してスレッドプールからスレッドを作成するタスクを待機し、すべてが非同期に実行されます。だから私は自分の仕事をするスレッドを作成することを達成しましたが、非同期でそれをしましたか?しかし、私は結果を返す必要はないことを考慮してください、私は結果を返さずに仕事をしたいだけです、本当にasync/awaitを使用する必要がありますか?
2番目の質問:
スレッドを非同期で実行する場合、どのように機能しますか?それはメインUIで実行されますが、別のスレッドで実行されますか、それとも別のスレッドで実行され、そのメソッドの内部で非同期に実行されますか?
C#でfire and forgetメソッドを実行する最も簡単な方法
タイプ Task<TResult>
では、タスクからTResult
を返す必要があります。返すものがない場合は、代わりに Task
を使用できます(これは、ちなみにTask<TResult>
の基本クラスです)。
ただし、タスクはスレッドではないことに注意してください。 タスクは実行されるジョブであり、スレッドはワーカーです。 プログラムが実行されると、ジョブとワーカーが使用可能および使用不可になります。背後では、ライブラリは利用可能なワーカーにジョブを割り当てます。新しいワーカーの作成はコストのかかる操作であるため、通常はスレッドプールを介して既存のワーカーを再利用することを好みます。
await
Task
を使用しない場合、またはawait
を使用しない場合、大きな違いがあります。
ケースしないawait
it:DoSomething
が呼び出されますが、DoSomething
Task
は完了していません。
ケースyou await
it:DoSomething
が呼び出され、次の文が実行されますDoSomething
Task
完了しました。
したがって、async
/await
の必要性は、DoSomething
の呼び出し方によって異なります。await
を呼び出さない場合は、火を消して道を忘れる。
それはメインUIで実行されますが、別のスレッドで実行されますか、それとも別のスレッドで実行され、そのメソッド内で非同期に実行されますか?
非同期コードは、他のスレッドを意味する場合があります(このQ&Aを参照してください 非同期とマルチスレッド-違いはありますか? )。つまり、コードがUIスレッドとは別のスレッドで実行されている場合、または再開中にUIスレッドの処理を続行できる場合、UIループは他のタスクが実行されている間に画面を更新できるため、 UIをフリーズせずに並列。
非同期メソッド(つまりasync
メソッド)は、await
ステートメントをステートマシンとして扱う必要があることをコンパイラーに伝えるための構文糖衣です。 C#コンパイラは、async
/await
コードをステートマシンに変換し、待機中のコードの後にTask
結果を待機するコードが実行されるようにします。
これらの他のQ&Aを確認することをお勧めします。
[...]しかし、これは、「async/await」がスレッドを起動し、Task.Runもスレッドを起動することを意味しますか、それとも両方が同じスレッドですか?
async
-await
を使用することは、「スレッドを作成する」という意味ではありません。継続をエレガントな方法で実装するのは単なる構文上の砂糖です。タスクはスレッドであってもなくてもかまいません。たとえば、Task.FromResult(true)
は、スレッドを作成する必要なしに非同期メソッドを実装できるように偽のタスクを作成します。
public Task<bool> SomeAsync()
{
// This way, this method either decides if its code is asynchronous or
// synchronous, but the caller can await it anyway!
return Task.FromResult(true);
}