DoboWiki
Top
> .NETプログラミング研究/44 をテンプレートにして作成
.NETプログラミング研究/44 をテンプレートにして作成
開始行:
#title(.NETプログラミング研究 第44号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第44号 [#n06037ae]
**.NET Tips [#n8c78676]
***時間のかかる処理の進行状況を表示する [#g0ca99f0]
#column(注意){{
この記事の最新版は「[[時間のかかる処理の進行状況を表示す...
}}
大きなファイルを読み込んだり、大量のファイルをコピーする...
ここでは単純な例として、次のようなアプリケーションを作成...
まずは、何も考えないで、Label.TextプロパティとProgressBar...
#code(vbnet){{
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'Button1のクリックイベントハンドラ
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
End Sub
}}
#code(csharp){{
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
}
}}
上記のコードを実行すると、ProgressBarは1秒おきにバーが伸...
ProgressBarコントロールのようにLabelコントロールでも1秒お...
#code(vbnet){{
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'Label1を再描画する
Label1.Update()
'(フォーム全体を再描画するには、次のようにする)
'Me.Update()
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
End Sub
}}
#code(csharp){{
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//Label1を再描画する
Label1.Update();
//(フォーム全体を再描画するには、次のようにする)
//this.Update();
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
}
}}
進行状況を表示するだけであれば、このようにUpdateメソッド...
Application.DoEventsメソッドを呼び出すと、キュー内で待機...
#code(vbnet){{
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'待機中のイベントを処理する
Application.DoEvents()
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
End Sub
}}
#code(csharp){{
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//待機中のイベントを処理する
Application.DoEvents();
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
}
}}
Application.DoEventsメソッド(あるいはマルチスレッドでも...
また、DoEventsメソッドならではの欠点もあります。イベント...
しかも、DoEventsメソッドが呼び出されイベントが処理される...
このようなDoEventsメソッドの欠点はマルチスレッドを使用す...
.NETのマルチスレッドプログラミングについては、このメール...
#code(vbnet){{
'ボタンのEnabledを変更するためのデリゲート
Delegate Sub SetButtonEnabledDelegate(ByVal en As Boolean)
'コントロールの値を変更するためのデリゲート
Delegate Sub SetProgressValueDelegate(ByVal num As Integer)
'別処理をするためのスレッド
Dim thread As System.Threading.Thread
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
'CountUpメソッドを別スレッドで処理する
thread = New System.Threading.Thread( _
New System.Threading.ThreadStart(AddressOf CountU...
thread.IsBackground = True
thread.Start()
End Sub
Private Sub CountUp()
'デリゲートの作成
Dim bdlg As New SetButtonEnabledDelegate( _
AddressOf SetButtonEnabled)
Dim dlg As New SetProgressValueDelegate( _
AddressOf SetProgressValue)
'Button1を無効にする
Me.Invoke(bdlg, New Object() {False})
Dim i As Integer
For i = 1 To 10
'コントロールの値を変更する
Me.Invoke(dlg, New Object() {i})
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
'Button1を有効に戻す
Me.Invoke(bdlg, New Object() {True})
End Sub
'コントロールの値を変更する
Private Sub SetProgressValue(ByVal num As Integer)
'ProgressBar1の値を変更する
ProgressBar1.Value = num
'Label1のテキストを変更する
Label1.Text = num.ToString()
End Sub
'ボタンのEnabledを変更する
Private Sub SetButtonEnabled(ByVal en As Boolean)
Button1.Enabled = en
End Sub
}}
#code(csharp){{
//ボタンのEnabledを変更するためのデリゲート
private delegate void SetButtonEnabledDelegate(bool en);
//コントロールの値を変更するためのデリゲート
private delegate void SetProgressValueDelegate(int num);
//別処理をするためのスレッド
private System.Threading.Thread thread;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
//CountUpメソッドを別スレッドで処理する
thread = new System.Threading.Thread(
new System.Threading.ThreadStart(CountUp));
thread.IsBackground = true;
thread.Start();
}
private void CountUp()
{
//デリゲートの作成
SetButtonEnabledDelegate bdlg =
new SetButtonEnabledDelegate(SetButtonEnabled);
SetProgressValueDelegate dlg =
new SetProgressValueDelegate(SetProgressValue);
//Button1を無効にする
this.Invoke(bdlg, new object[] {false});
for (int i = 1; i <= 10; i++)
{
//コントロールの値を変更する
this.Invoke(dlg, new object[] {i});
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
//Button1を有効に戻す
this.Invoke(bdlg, new object[] {true});
}
//コントロールの値を変更する
private void SetProgressValue(int num)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = num;
//Label1のテキストを変更する
Label1.Text = num.ToString();
}
//ボタンのEnabledを変更する
private void SetButtonEnabled(bool en)
{
Button1.Enabled = en;
}
}}
以上のように、Application.DoEventsメソッドを使う方法と、...
***時間のかかる処理をユーザーが停止できるようにする [#pe7...
#column(注意){{
この記事の最新版は「[[時間のかかる処理をユーザーが停止で...
}}
次に、時間のかかる処理をユーザーがキャンセルボタンをクリ...
先の「時間のかかる処理の進行状況を表示する」で考察した通...
DoEventsメソッドを使用する場合は、キャンセルボタンがクリ...
このようにして「時間のかかる処理の進行状況を表示する」の...
#code(vbnet){{
'キャンセルボタンがクリックされたか
Private canceled As Boolean = False
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
'初期化
Button1.Enabled = False
Button2.Enabled = True
canceled = False
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'待機中のイベントを処理する
Application.DoEvents()
'キャンセルボタンがクリックされたか調べる
If canceled Then
'キャンセルボタンがクリックされた時
MessageBox.Show(Me, "ユーザーにより中止されま...
'ループを抜ける
Exit For
End If
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
'終了時の処理
Button1.Enabled = True
Button2.Enabled = False
End Sub
'Button2のクリックイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button2.Click
'フラッグを立てる
canceled = True
End Sub
}}
#code(csharp){{
//キャンセルボタンがクリックされたか
private bool canceled = false;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
//初期化
Button1.Enabled = false;
Button2.Enabled = true;
canceled = false;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//待機中のイベントを処理する
Application.DoEvents();
//キャンセルボタンがクリックされたか調べる
if (canceled)
{
//キャンセルボタンがクリックされた時
MessageBox.Show(this, "ユーザーにより中止され...
//ループを抜ける
break;
}
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
//終了時の処理
Button1.Enabled = true;
Button2.Enabled = false;
}
//Button2のクリックイベントハンドラ
private void Button2_Click(object sender, System.EventArg...
{
//フラッグを立てる
canceled = true;
}
}}
次はマルチスレッドを使った方法です。この場合、キャンセル...
以下にこのような方法により、「時間のかかる処理の進行状況...
#code(vbnet){{
'キャンセルボタンがクリックされたか
Private canceled As Boolean = False
'ボタンのEnabledを変更するためのデリゲート
Delegate Sub SetButtonEnabledDelegate(ByVal en As Boo...
'コントロールの値を変更するためのデリゲート
Delegate Sub SetProgressValueDelegate(ByVal num As In...
'別処理をするためのスレッド
Private thread As System.Threading.Thread
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
'CountUpメソッドを別スレッドで処理する
thread = New System.Threading.Thread( _
New System.Threading.ThreadStart(AddressOf Co...
thread.IsBackground = True
thread.Start()
End Sub
'Button2のクリックイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button2.Click
'フラッグを立てる
canceled = True
End Sub
Private Sub CountUp()
'デリゲートの作成
Dim bdlg As New SetButtonEnabledDelegate( _
AddressOf SetButtonEnabled)
Dim dlg As New SetProgressValueDelegate( _
AddressOf SetProgressValue)
'Button1を無効にする
Me.Invoke(bdlg, New Object() {False})
Dim i As Integer
For i = 1 To 10
'キャンセルボタンがクリックされたか調べる
If canceled Then
'キャンセルボタンがクリックされた時
MessageBox.Show(Me, "ユーザーにより中止さ...
'ループを抜ける
Exit For
End If
'コントロールの値を変更する
Me.Invoke(dlg, New Object() {i})
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
'Button1を有効に戻す
Me.Invoke(bdlg, New Object() {True})
End Sub
'コントロールの値を変更する
Private Sub SetProgressValue(ByVal num As Integer)
'ProgressBar1の値を変更する
ProgressBar1.Value = num
'Label1のテキストを変更する
Label1.Text = num.ToString()
End Sub
'ボタンのEnabledを変更する
Private Sub SetButtonEnabled(ByVal en As Boolean)
Button1.Enabled = en
End Sub
}}
#code(csharp){{
//キャンセルボタンがクリックされたか
private volatile bool canceled = false;
//ボタンのEnabledを変更するためのデリゲート
private delegate void SetButtonEnabledDelegate(bool en);
//コントロールの値を変更するためのデリゲート
private delegate void SetProgressValueDelegate(int num);
//別処理をするためのスレッド
private System.Threading.Thread thread;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
//CountUpメソッドを別スレッドで処理する
thread = new System.Threading.Thread(
new System.Threading.ThreadStart(CountUp));
thread.IsBackground = true;
thread.Start();
}
//Button2のクリックイベントハンドラ
private void Button2_Click(object sender, System.EventArg...
{
//フラッグを立てる
canceled = true;
}
private void CountUp()
{
//デリゲートの作成
SetButtonEnabledDelegate bdlg =
new SetButtonEnabledDelegate(SetButtonEnabled);
SetProgressValueDelegate dlg =
new SetProgressValueDelegate(SetProgressValue);
//Button1を無効にする
this.Invoke(bdlg, new object[] {false});
for (int i = 1; i <= 10; i++)
{
//キャンセルボタンがクリックされたか調べる
if (canceled)
{
//キャンセルボタンがクリックされた時
MessageBox.Show(this, "ユーザーにより中止され...
//ループを抜ける
break;
}
//コントロールの値を変更する
this.Invoke(dlg, new object[] {i});
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
//Button1を有効に戻す
this.Invoke(bdlg, new object[] {true});
}
//コントロールの値を変更する
private void SetProgressValue(int num)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = num;
//Label1のテキストを変更する
Label1.Text = num.ToString();
}
//ボタンのEnabledを変更する
private void SetButtonEnabled(bool en)
{
Button1.Enabled = en;
}
}}
最後にダイアログ使って進行状況を表示し、キャンセルできる...
**コメント [#dd94c2f0]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2004-10-27 (水) 06:00:00,DOB...
終了行:
#title(.NETプログラミング研究 第44号)
#navi(.NETプログラミング研究)
#contents
*.NETプログラミング研究 第44号 [#n06037ae]
**.NET Tips [#n8c78676]
***時間のかかる処理の進行状況を表示する [#g0ca99f0]
#column(注意){{
この記事の最新版は「[[時間のかかる処理の進行状況を表示す...
}}
大きなファイルを読み込んだり、大量のファイルをコピーする...
ここでは単純な例として、次のようなアプリケーションを作成...
まずは、何も考えないで、Label.TextプロパティとProgressBar...
#code(vbnet){{
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'Button1のクリックイベントハンドラ
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
End Sub
}}
#code(csharp){{
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
}
}}
上記のコードを実行すると、ProgressBarは1秒おきにバーが伸...
ProgressBarコントロールのようにLabelコントロールでも1秒お...
#code(vbnet){{
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'Label1を再描画する
Label1.Update()
'(フォーム全体を再描画するには、次のようにする)
'Me.Update()
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
End Sub
}}
#code(csharp){{
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//Label1を再描画する
Label1.Update();
//(フォーム全体を再描画するには、次のようにする)
//this.Update();
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
}
}}
進行状況を表示するだけであれば、このようにUpdateメソッド...
Application.DoEventsメソッドを呼び出すと、キュー内で待機...
#code(vbnet){{
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'待機中のイベントを処理する
Application.DoEvents()
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
End Sub
}}
#code(csharp){{
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//待機中のイベントを処理する
Application.DoEvents();
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
}
}}
Application.DoEventsメソッド(あるいはマルチスレッドでも...
また、DoEventsメソッドならではの欠点もあります。イベント...
しかも、DoEventsメソッドが呼び出されイベントが処理される...
このようなDoEventsメソッドの欠点はマルチスレッドを使用す...
.NETのマルチスレッドプログラミングについては、このメール...
#code(vbnet){{
'ボタンのEnabledを変更するためのデリゲート
Delegate Sub SetButtonEnabledDelegate(ByVal en As Boolean)
'コントロールの値を変更するためのデリゲート
Delegate Sub SetProgressValueDelegate(ByVal num As Integer)
'別処理をするためのスレッド
Dim thread As System.Threading.Thread
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
'CountUpメソッドを別スレッドで処理する
thread = New System.Threading.Thread( _
New System.Threading.ThreadStart(AddressOf CountU...
thread.IsBackground = True
thread.Start()
End Sub
Private Sub CountUp()
'デリゲートの作成
Dim bdlg As New SetButtonEnabledDelegate( _
AddressOf SetButtonEnabled)
Dim dlg As New SetProgressValueDelegate( _
AddressOf SetProgressValue)
'Button1を無効にする
Me.Invoke(bdlg, New Object() {False})
Dim i As Integer
For i = 1 To 10
'コントロールの値を変更する
Me.Invoke(dlg, New Object() {i})
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
'Button1を有効に戻す
Me.Invoke(bdlg, New Object() {True})
End Sub
'コントロールの値を変更する
Private Sub SetProgressValue(ByVal num As Integer)
'ProgressBar1の値を変更する
ProgressBar1.Value = num
'Label1のテキストを変更する
Label1.Text = num.ToString()
End Sub
'ボタンのEnabledを変更する
Private Sub SetButtonEnabled(ByVal en As Boolean)
Button1.Enabled = en
End Sub
}}
#code(csharp){{
//ボタンのEnabledを変更するためのデリゲート
private delegate void SetButtonEnabledDelegate(bool en);
//コントロールの値を変更するためのデリゲート
private delegate void SetProgressValueDelegate(int num);
//別処理をするためのスレッド
private System.Threading.Thread thread;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
//CountUpメソッドを別スレッドで処理する
thread = new System.Threading.Thread(
new System.Threading.ThreadStart(CountUp));
thread.IsBackground = true;
thread.Start();
}
private void CountUp()
{
//デリゲートの作成
SetButtonEnabledDelegate bdlg =
new SetButtonEnabledDelegate(SetButtonEnabled);
SetProgressValueDelegate dlg =
new SetProgressValueDelegate(SetProgressValue);
//Button1を無効にする
this.Invoke(bdlg, new object[] {false});
for (int i = 1; i <= 10; i++)
{
//コントロールの値を変更する
this.Invoke(dlg, new object[] {i});
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
//Button1を有効に戻す
this.Invoke(bdlg, new object[] {true});
}
//コントロールの値を変更する
private void SetProgressValue(int num)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = num;
//Label1のテキストを変更する
Label1.Text = num.ToString();
}
//ボタンのEnabledを変更する
private void SetButtonEnabled(bool en)
{
Button1.Enabled = en;
}
}}
以上のように、Application.DoEventsメソッドを使う方法と、...
***時間のかかる処理をユーザーが停止できるようにする [#pe7...
#column(注意){{
この記事の最新版は「[[時間のかかる処理をユーザーが停止で...
}}
次に、時間のかかる処理をユーザーがキャンセルボタンをクリ...
先の「時間のかかる処理の進行状況を表示する」で考察した通...
DoEventsメソッドを使用する場合は、キャンセルボタンがクリ...
このようにして「時間のかかる処理の進行状況を表示する」の...
#code(vbnet){{
'キャンセルボタンがクリックされたか
Private canceled As Boolean = False
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
'初期化
Button1.Enabled = False
Button2.Enabled = True
canceled = False
Dim i As Integer
For i = 1 To 10
'ProgressBar1の値を変更する
ProgressBar1.Value = i
'Label1のテキストを変更する
Label1.Text = i.ToString()
'待機中のイベントを処理する
Application.DoEvents()
'キャンセルボタンがクリックされたか調べる
If canceled Then
'キャンセルボタンがクリックされた時
MessageBox.Show(Me, "ユーザーにより中止されま...
'ループを抜ける
Exit For
End If
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
'終了時の処理
Button1.Enabled = True
Button2.Enabled = False
End Sub
'Button2のクリックイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button2.Click
'フラッグを立てる
canceled = True
End Sub
}}
#code(csharp){{
//キャンセルボタンがクリックされたか
private bool canceled = false;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
//初期化
Button1.Enabled = false;
Button2.Enabled = true;
canceled = false;
for (int i = 1; i <= 10; i++)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = i;
//Label1のテキストを変更する
Label1.Text = i.ToString();
//待機中のイベントを処理する
Application.DoEvents();
//キャンセルボタンがクリックされたか調べる
if (canceled)
{
//キャンセルボタンがクリックされた時
MessageBox.Show(this, "ユーザーにより中止され...
//ループを抜ける
break;
}
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
//終了時の処理
Button1.Enabled = true;
Button2.Enabled = false;
}
//Button2のクリックイベントハンドラ
private void Button2_Click(object sender, System.EventArg...
{
//フラッグを立てる
canceled = true;
}
}}
次はマルチスレッドを使った方法です。この場合、キャンセル...
以下にこのような方法により、「時間のかかる処理の進行状況...
#code(vbnet){{
'キャンセルボタンがクリックされたか
Private canceled As Boolean = False
'ボタンのEnabledを変更するためのデリゲート
Delegate Sub SetButtonEnabledDelegate(ByVal en As Boo...
'コントロールの値を変更するためのデリゲート
Delegate Sub SetProgressValueDelegate(ByVal num As In...
'別処理をするためのスレッド
Private thread As System.Threading.Thread
'Button1のクリックイベントハンドラ
Private Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'ProgressBar1の設定
ProgressBar1.Minimum = 1
ProgressBar1.Maximum = 10
'CountUpメソッドを別スレッドで処理する
thread = New System.Threading.Thread( _
New System.Threading.ThreadStart(AddressOf Co...
thread.IsBackground = True
thread.Start()
End Sub
'Button2のクリックイベントハンドラ
Private Sub Button2_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button2.Click
'フラッグを立てる
canceled = True
End Sub
Private Sub CountUp()
'デリゲートの作成
Dim bdlg As New SetButtonEnabledDelegate( _
AddressOf SetButtonEnabled)
Dim dlg As New SetProgressValueDelegate( _
AddressOf SetProgressValue)
'Button1を無効にする
Me.Invoke(bdlg, New Object() {False})
Dim i As Integer
For i = 1 To 10
'キャンセルボタンがクリックされたか調べる
If canceled Then
'キャンセルボタンがクリックされた時
MessageBox.Show(Me, "ユーザーにより中止さ...
'ループを抜ける
Exit For
End If
'コントロールの値を変更する
Me.Invoke(dlg, New Object() {i})
'1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000)
Next i
'Button1を有効に戻す
Me.Invoke(bdlg, New Object() {True})
End Sub
'コントロールの値を変更する
Private Sub SetProgressValue(ByVal num As Integer)
'ProgressBar1の値を変更する
ProgressBar1.Value = num
'Label1のテキストを変更する
Label1.Text = num.ToString()
End Sub
'ボタンのEnabledを変更する
Private Sub SetButtonEnabled(ByVal en As Boolean)
Button1.Enabled = en
End Sub
}}
#code(csharp){{
//キャンセルボタンがクリックされたか
private volatile bool canceled = false;
//ボタンのEnabledを変更するためのデリゲート
private delegate void SetButtonEnabledDelegate(bool en);
//コントロールの値を変更するためのデリゲート
private delegate void SetProgressValueDelegate(int num);
//別処理をするためのスレッド
private System.Threading.Thread thread;
//Button1のクリックイベントハンドラ
private void Button1_Click(object sender, System.EventArg...
{
//ProgressBar1の設定
ProgressBar1.Minimum = 1;
ProgressBar1.Maximum = 10;
//CountUpメソッドを別スレッドで処理する
thread = new System.Threading.Thread(
new System.Threading.ThreadStart(CountUp));
thread.IsBackground = true;
thread.Start();
}
//Button2のクリックイベントハンドラ
private void Button2_Click(object sender, System.EventArg...
{
//フラッグを立てる
canceled = true;
}
private void CountUp()
{
//デリゲートの作成
SetButtonEnabledDelegate bdlg =
new SetButtonEnabledDelegate(SetButtonEnabled);
SetProgressValueDelegate dlg =
new SetProgressValueDelegate(SetProgressValue);
//Button1を無効にする
this.Invoke(bdlg, new object[] {false});
for (int i = 1; i <= 10; i++)
{
//キャンセルボタンがクリックされたか調べる
if (canceled)
{
//キャンセルボタンがクリックされた時
MessageBox.Show(this, "ユーザーにより中止され...
//ループを抜ける
break;
}
//コントロールの値を変更する
this.Invoke(dlg, new object[] {i});
//1秒間待機する(本来なら何らかの処理を行う)
System.Threading.Thread.Sleep(1000);
}
//Button1を有効に戻す
this.Invoke(bdlg, new object[] {true});
}
//コントロールの値を変更する
private void SetProgressValue(int num)
{
//ProgressBar1の値を変更する
ProgressBar1.Value = num;
//Label1のテキストを変更する
Label1.Text = num.ToString();
}
//ボタンのEnabledを変更する
private void SetButtonEnabled(bool en)
{
Button1.Enabled = en;
}
}}
最後にダイアログ使って進行状況を表示し、キャンセルできる...
**コメント [#dd94c2f0]
#comment
//これより下は編集しないでください
#pageinfo([[:Category/.NET]],2004-10-27 (水) 06:00:00,DOB...
ページ名:
▲
▼
[
トップ
] [
新規
|
子ページ作成
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]