まず、背景情報を少し。WinRT での実行に適した既存の C# ライブラリ コードを作成中です。このコードの奥深くで小さなファイル IO を実行する必要がある部分があるため、最初にすべての IO が完了するまでタスクの同期を維持し、Task.Wait() を使用してメイン スレッドを停止しようとしました。
案の定、それがデッドロックにつながることがすぐにわかりました。
その後、プロトタイプを「非同期」にするために多くのコードを変更していることに気付きました。つまり、async キーワードと await キーワードを挿入し、それに応じてメソッドの戻り値の型を変更していました。これは大変な作業でした (実際には無意味な作業が多すぎます) が、この方法でプロトタイプを動作させることができました。
次に、実験を行い、別のスレッドでWait ステートメントを使用して元のコードを実行しました。
System.Threading.Tasks.Task.Run(()=> Draw(..., cancellationToken)
デッドロックなし!
非同期プログラミングがどのように機能するかを理解していると思っていたので、今、私は真剣に混乱しています。私たちのコードは、(まだ) ConfigureAwait(false) をまったく使用していません。したがって、すべての await ステートメントは、呼び出されたときと同じコンテキストで継続する必要があります。私はそれが意味すると仮定しました:同じスレッド。このスレッドが「Wait」を呼び出した場合、これもデッドロックにつながるはずです。しかし、そうではありません。
明確で堅実な説明を持っている人はいますか?
これに対する答えは、多くの条件付き async/await キーワードを挿入してコードをめちゃくちゃにするか、それともコードをきれいに保ち、あちこちで Wait() を実行するスレッドを使用するかを決定します。継続がブロックされていない任意のスレッドによって実行される場合、問題はありません。ただし、それらが UI スレッドによって実行される場合、継続の計算コストが高いと問題が発生する可能性があります。
問題が明確になることを願っています。そうでない場合は、お知らせください。