質問: WPFでの非同期処理について勉強しております。 いろいろ調べてみた結果非同期自体の処理はできましたが、なぜ動いているのか理解できませんでした。 理解している点として ・ボタンクリック時の関数に`async`をつけることで非同期での処理ができる ・この関数自体はUIスレッドで動いており、新しくタスクを生成すると別スレッドで動く は理解しました。 ですがこの関数はUIスレッドで動いているため タスクが終了するまでUIスレッドが止まる気がします。 私の中ではUIが固まり操作できなくなると思っているのですが とくに固まることなく動いているのが疑問です。 理解が間違っているのでしょうか? ### 試したこと 実際同じスレッドか確かめるため非同期用の関数と普通のクリック関数でスレッドIDを出力 →同じIDだった 同時にUIの操作ができるか確かめるためそれぞれの関数からTextBoxを操作 →非同期の関数がUIを更新していても、別関数から操作可能 ### ソースコード ``` ``` ``` private async void Button_Click1(object sender, RoutedEventArgs e) { while (true) { await Task.Delay(1); text.AppendText("buttonClick1\n"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: ButtonClick1"); } } private void Button_Click2(object sender, RoutedEventArgs e) { text.AppendText("buttonClick2\n"); Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId}: ButtonClick2"); } ``` また上記のソースコードで`Button_Click1`関数内で awaitの行をコメントアウトすると完全にUIが固まってしまう理由も知りたいです。 ### 補足情報(FW/ツールのバージョンなど) Visual Studio Community 2017を使用
回答: await は、そこでスレッドを停止して次の処理を**呼ぶのを**待てという命令ではありません。処理を停止して再度**呼ばれるのを**待てという命令です。 不正確ですが、await Task Delay(1) は、そこで一度 return し、1ms 後にまた元の状態を回復して続きから始めるに近いものだと思ってください。 例えば yield return のようなものとイメージしてみれば良いかもしれません。yield return は非同期ではありませんが、そこで処理が一度中断されて呼び出し元に戻るという点では似ています。