質問するログイン新規登録

回答編集履歴

3

追記

2016/11/02 02:23

投稿

catsforepaw
catsforepaw

スコア5944

answer CHANGED
@@ -6,4 +6,31 @@
6
6
  とりあえずの回避策としては、`loop_progressbar = false;`をTask.Runの中の処理の最後に書いてみてください。
7
7
  あと、念のためrunメソッドの`loop_progressbar = true;`は`MakeCsvAsync();`の前に書いてください。
8
8
 
9
- `async`メソッド内の`await`後の処理は、フォームが何もメソッドを実行していない状態の時に実行されるという点に注意してください。
9
+ `async`メソッド内の`await`後の処理は、フォームが何もメソッドを実行していない状態の時に実行されるという点に注意してください。
10
+
11
+ ---
12
+ 追記
13
+
14
+ runメソッド内で時間のかかる処理(別スレッドの処理待ち)をするのは得策ではありません。その間、フォームに対するあらゆる操作ができなくなりますし、プログレスバーのハイライトのアニメーションが見られなくなります。
15
+
16
+ こんな感じに書いた方がシンプルで判りやすいですし、UIが固まることもありません。
17
+ ```C#
18
+ private async void run()
19
+ {
20
+ // 再突入抑止のためボタン無効化(ボタン押下でrunメソッドが呼ばれると仮定)
21
+ button1.Enabled = false;
22
+
23
+ for(int i = 0; i < 1000; i++)
24
+ {
25
+ await Task.Run(() =>
26
+ {
27
+ // ファイル1個作成
28
+ });
29
+ progressBar1.Value = i + 1;
30
+ }
31
+ MessageBox.Show("完了しました。");
32
+
33
+ // ボタン有効化
34
+ button1.Enabled = true;
35
+ }
36
+ ```

2

ちょっと誤解の恐れがある一文を削除

2016/11/02 02:23

投稿

catsforepaw
catsforepaw

スコア5944

answer CHANGED
@@ -6,4 +6,4 @@
6
6
  とりあえずの回避策としては、`loop_progressbar = false;`をTask.Runの中の処理の最後に書いてみてください。
7
7
  あと、念のためrunメソッドの`loop_progressbar = true;`は`MakeCsvAsync();`の前に書いてください。
8
8
 
9
- `async`メソッド内の`await`後の処理は、フォームが何もメソッドを実行していない状態の時に(他のメソッド実行の合間に)実行されるという点に注意してください。
9
+ `async`メソッド内の`await`後の処理は、フォームが何もメソッドを実行していない状態の時に実行されるという点に注意してください。

1

追記

2016/11/01 14:10

投稿

catsforepaw
catsforepaw

スコア5944

answer CHANGED
@@ -4,5 +4,6 @@
4
4
  ところが、`MakeCsvAsync`メソッドは`run`メソッド内から呼び出されており、`run`メソッドは`loop_progressbar == true`の間ループしてメソッドから抜けないのでUIスレッドを占有した状態となり、`await`の続きを実行することができません。結果、`loop_progressbar`がいつまでたってもfalseにならず、`run`メソッド内で永久ループになってしまっています。
5
5
 
6
6
  とりあえずの回避策としては、`loop_progressbar = false;`をTask.Runの中の処理の最後に書いてみてください。
7
+ あと、念のためrunメソッドの`loop_progressbar = true;`は`MakeCsvAsync();`の前に書いてください。
7
8
 
8
9
  `async`メソッド内の`await`後の処理は、フォームが何もメソッドを実行していない状態の時に(他のメソッド実行の合間に)実行されるという点に注意してください。