質問: num / 1000; } } catch(Exception e) { MessageBox.Show(e.Message); } } ``` ファイルの作成自体は、1000個で約一分半ほどです。 よろしくお願いいたします。
回答: async/awaitの挙動を理解できていないのが原因ですね。少々ややこしいです。 `MakeCsvAsync`メソッドで`await Task.Run`を実行すると、別スレッドでその中身を実行開始してすぐに一旦UIスレッドに制御を返します。そして、別スレッドでの処理終了後にUIスレッドでその続きが実行されます。 ところが、`MakeCsvAsync`メソッドは`run`メソッド内から呼び出されており、`run`メソッドは`loop_progressbar == true`の間ループしてメソッドから抜けないのでUIスレッドを占有した状態となり、`await`の続きを実行することができません。結果、`loop_progressbar`がいつまでたってもfalseにならず、`run`メソッド内で永久ループになってしまっています。 とりあえずの回避策としては、`loop_progressbar = false;`をTask.Runの中の処理の最後に書いてみてください。 あと、念のためrunメソッドの`loop_progressbar = true;`は`MakeCsvAsync();`の前に書いてください。 `async`メソッド内の`await`後の処理は、フォームが何もメソッドを実行していない状態の時に実行されるという点に注意してください。 追記 runメソッド内で時間のかかる処理(別スレッドの処理待ち)をするのは得策ではありません。その間、フォームに対するあらゆる操作ができなくなりますし、プログレスバーのハイライトのアニメーションが見られなくなります。 こんな感じに書いた方がシンプルで判りやすいですし、UIが固まることもありません。 ``` private async void run() { // 再突入抑止のためボタン無効化(ボタン押下でrunメソッドが呼ばれると仮定) button1.Enabled = false; for(int i = 0; i < 1000; i++) { await Task.Run(() => { // ファイル1個作成 }); progressBar1.Value = i + 1; } MessageBox.Show("完了しました。"); // ボタン有効化 button1.Enabled = true; } ```