時間のかかる処理を行っている最中に画面の情報を更新する場合、画面の更新が適切に行われないことがあります。
例えば、以下のようなコードを記述すると、画面の更新が上手く行われていないことが確認できます。
これを回避する方法について説明します。
以下のコードの期待する結果としては、以下を想定しています。
・テキストの値が「1, 2, 3, ... 9999, 10000」と切り替わる。
・プログレスバーが徐々に100%に近付いていく。
(最終的に100%になる)
上記のコードを実行すると、以下のような結果になります。
・テキストの値は、10000と表示されるだけである。
・プログレスバーの進み具合が飛び飛びになっている感じがする。
この事象は、一連の処理内で画面の再描画が行われていないために発生しています。この状態を回避するためには、フォームオブジェクトのRefresh()メソッドを利用します。
以下、サンプルです。
上記を実行すると、期待した通りの結果が得られます。
・テキストの値が「1, 2, 3, ... 9999, 10000」と表示される。
・プログレスバーの進み具合が滑らかに表示される。
【補足事項】
・一連の処理中に複数回、値を変更する場合には、画面の再描画が必要になります。
・Refreshメソッドを実行すると、パフォーマンスが低下します。
大量のデータを処理する場合には、Refreshメソッドの実行タイミングに注意して下さい。1件毎にRefreshメソッドを実行してしまうと、パフォーマンスが大幅に低下します。
このような場合には、ブロック単位(10件単位や100件単位)にRefreshメソッドを実行する等して、パフォーマンスとの折り合いをつけましょう。
・Application.DoEvents()でも代用可能ですが、お勧めしません。
理由は、以下の通りです。
1.データが正しく表示される保証がない。
→上記のサンプルを実行すると、プログレスバーとテキストの値にずれが生じます。
2.Windowsメッセージが処理されてしまう。
→ボタン押下時のイベント等が実行されてしまう可能性がある。
※Refreshメソッドよりも処理は早いのですが…
・C#で作成している場合でも、この事象は発生します。
例えば、以下のようなコードを記述すると、画面の更新が上手く行われていないことが確認できます。
これを回避する方法について説明します。
以下のコードの期待する結果としては、以下を想定しています。
・テキストの値が「1, 2, 3, ... 9999, 10000」と切り替わる。
・プログレスバーが徐々に100%に近付いていく。
(最終的に100%になる)
Public Class Form1
Private Sub Button1_Click( _
ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar1.Maximum = 10000
ProgressBar1.Minimum = 1
ProgressBar1.Value = 1
For idx As Long = 1 To 10000
ProgressBar1.Value = idx
TextBox1.Text = idx
Next idx
End Sub
End Class
上記のコードを実行すると、以下のような結果になります。
・テキストの値は、10000と表示されるだけである。
・プログレスバーの進み具合が飛び飛びになっている感じがする。
この事象は、一連の処理内で画面の再描画が行われていないために発生しています。この状態を回避するためには、フォームオブジェクトのRefresh()メソッドを利用します。
以下、サンプルです。
Public Class Form1
Private Sub Button1_Click( _
ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles Button1.Click
ProgressBar1.Maximum = 10000
ProgressBar1.Minimum = 1
ProgressBar1.Value = 1
For idx As Long = 1 To 10000
ProgressBar1.Value = idx
TextBox1.Text = idx
'以下を1文を追加
Me.Refresh()
Next idx
End Sub
End Class
上記を実行すると、期待した通りの結果が得られます。
・テキストの値が「1, 2, 3, ... 9999, 10000」と表示される。
・プログレスバーの進み具合が滑らかに表示される。
【補足事項】
・一連の処理中に複数回、値を変更する場合には、画面の再描画が必要になります。
・Refreshメソッドを実行すると、パフォーマンスが低下します。
大量のデータを処理する場合には、Refreshメソッドの実行タイミングに注意して下さい。1件毎にRefreshメソッドを実行してしまうと、パフォーマンスが大幅に低下します。
このような場合には、ブロック単位(10件単位や100件単位)にRefreshメソッドを実行する等して、パフォーマンスとの折り合いをつけましょう。
・Application.DoEvents()でも代用可能ですが、お勧めしません。
理由は、以下の通りです。
1.データが正しく表示される保証がない。
→上記のサンプルを実行すると、プログレスバーとテキストの値にずれが生じます。
2.Windowsメッセージが処理されてしまう。
→ボタン押下時のイベント等が実行されてしまう可能性がある。
※Refreshメソッドよりも処理は早いのですが…
・C#で作成している場合でも、この事象は発生します。
- カテゴリ:
- VB.NET