質問: C# WPF 初歩的なことで申し訳ないのですが、予め準備してあるデータをループなどで処理しているときにMainWindowが操作不能になるはどうにかできないのでしょうか? Timerを用いて無限ループを回避しても、一定時間は動くのがとまってしまいます。 何か解決方法、もしくは仕組みについての参考文献等があればお教えいただきたいです。
回答: .NETはUI動作と内部動作を独立させる機能として、async/await(TAP)を利用できます。 ・他の言語に比べUI非同期機能がかなり低レベルに実装されているため、 組み方を間違えるとすぐハングします。作法にのっとって実装する必要があります。 例えばasync/await(TAP)で並列処理を実装しようとすると、大抵うまくいきません。 async/await(TAP)はUIとバック処理を分離する目的用と割り切って使った方がいいです。 ・作法にのっとって実装していくと、ほぼ全てのメソッドをasync化する必要があるため、 編集範囲が広大になります。(既存のメソッドにasync修飾子をつけて戻り値も機械的にTaskまたはTaskに置き換えるだけですが) ・asyncメソッドは、ref/out引数が使用できません。 複数の値を返したい場合は、Tupleなどで書き直す必要があります。 要約 1. asyncしたいメソッドはasync修飾子つけ、Asyncサフィックスをつける 2. awaitでの呼び出しが必要なasyncメソッドは、asyncメソッド内でしか呼び出せない 3. 1, 2より、既存の自作メソッドが全てasyncになっていく。 4. 場合によっては、標準ライブラリもAsync対応版を覚えなおす必要が出てくる。 書き換え自体は非常に単調なので、そんなに難しくはありません。 1. 呼び出し元から非同期で動作させたいメソッドの戻り値を機械的に次のように書き換える。 ただし、ref/outを使用している場合は、Tuple等で複数返すように調整する void → Task void以外 → Task 2. 1のメソッド定義にasync修飾子を追加し、Asyncサフィックスをついたものにリネームする。 3. 1を呼び出しているメソッド全ても1,2の処理を行う。 4. 以下、1~3を最初の呼び出し元まで繰り返す