アクセス数 累計:000,125,028 昨日:000,000,099 本日:000,000,050
|
|
|
|
【Amazon ランキング:ゲーム - キッズ・ニンテンドー3DS】
|
|
前回まで作成したプログラムはプログレスバーを更新するためにタイマーコントロールを使用していましたがこれには理由があります。
直接サブスレッドからプログレスバーの値を変更すればタイマーは必要なくなるのですがそうすると例外は発生してしまいます。
それは、「コントロールはそのハンドルを所有しているスレッドからしか操作できない」という制約があるためです。
|
|
Invoke() メソッド |
|
サブスレッドからコントロールを操作するには Invoke() メソッドを使用します。
Invoke() メソッドを使用することによってサブスレッドからメインスレッドのメソッドを呼ぶことができます。そうすることでアクセスの制約を回避することが可能になります。 |
|
それではまず Invoke() ためのメソッドを作成します。メソッドを呼ぶためにデリケーターを経由しますので呼び出すメソッドの引数ににあわせてデリゲーターを作成してください。
[VB]
' プログレスバー更新処理用デリゲータ
Delegate Sub delegate_UpdateProgressBar(ByVal value As Integer)
' プログレスバー更新処理
Private Sub UpdateProgressBar(ByVal value As Integer)
' プログレスバー更新
Me.progressBar1.Value = value
End Sub
[C#]
// プログレスバー更新処理用デリゲータ
delegate void delegate_UpdateProgressBar(int value);
// プログレスバー更新処理
private void UpdateProgressBar(int value)
{
// プログレスバー更新
this.progressBar1.Value = value;
}
次にサブスレッドからメインスレッドのコントロールに対して Invoke() メソッドを呼び出します。
[VB]
' プログレスバー更新
Dim callback As delegate_UpdateProgressBar = _
New delegate_UpdateProgressBar(AddressOf UpdateProgressBar)
' Invoke してメインスレッドからメソッドを呼び出す
Me.progressBar1.Invoke(callback, _progressValue)
[C#]
// プログレスバー更新
delegate_UpdateProgressBar callback =
new delegate_UpdateProgressBar(UpdateProgressBar);
// Invoke してメインスレッドからメソッドを呼び出す
this.progressBar1.Invoke(callback, _progressValue);
※Invoke() メソッドで複数の引数を渡す場合には Object 配列を使います。
[VB]
Me.Control.Invoke(callback, New Object() {arg1, arg2, arg3})
[C#]
this.Control.Invoke(callback, new object[]{arg1, arg2, arg3});
|
フォームの作成 |
|
画面は前回とほぼ同じですが、
Timer は必要ありません。
Button:[Button1]
ProgressBar:[ProgressBar1]
|
|
VB[Form1.vb] |
Imports System.Threading
Public Class Form1
Private _progressValue As Integer = 0
Private _thread As Thread = Nothing
Public Sub New()
' この呼び出しは、Windows フォーム デザイナで必要です。
InitializeComponent()
End Sub
Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles button1.Click
If Not _thread Is Nothing Then
Console.WriteLine(_thread.ThreadState.ToString())
' スレッドが停止状態でない場合は終了
If _thread.ThreadState <> ThreadState.Stopped Then
Exit Sub
End If
End If
' スレッド開始
_thread = New Thread(AddressOf ThreadProc)
_thread.Start()
End Sub
Private Sub Form1_FormClosed( _
ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) _
Handles Me.FormClosed
' スレッドを強制終了させる
_thread.Abort()
' メインスレッドに結合する
_thread.Join()
End Sub
' スレッド処理
Private Sub ThreadProc()
Try
For i As Integer = 0 To 10
'プログレスの値加算
_progressValue = i * 10
' プログレスバー更新
Dim callback As delegate_UpdateProgressBar = _
New delegate_UpdateProgressBar(AddressOf UpdateProgressBar)
' Invoke してメインスレッドからメソッドを呼び出す
Me.progressBar1.Invoke(callback, _progressValue)
Thread.Sleep(1000)
Next
Catch ex As ThreadAbortException
Console.WriteLine("スレッド強制終了!")
End Try
End Sub
' プログレスバー更新処理用デリゲータ
Delegate Sub delegate_UpdateProgressBar(ByVal value As Integer)
' プログレスバー更新処理
Private Sub UpdateProgressBar(ByVal value As Integer)
' プログレスバー更新
Me.progressBar1.Value = value
End Sub
End Class
|
|
C#[Form1.cs] |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadCS
{
public partial class Form1 : Form
{
private int _progressValue = 0;
private Thread _thread = null;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (_thread != null)
{
Console.WriteLine(_thread.ThreadState.ToString());
// スレッドが停止状態でない場合は終了
if (_thread.ThreadState != ThreadState.Stopped)
return;
}
// スレッド開始
_thread = new Thread(ThreadProc);
_thread.Start();
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
// スレッドを強制終了させる
_thread.Abort();
// メインスレッドに結合する
_thread.Join();
}
// スレッド処理
private void ThreadProc()
{
try
{
for (int i = 0; i <= 10; i++)
{
// プログレスの値加算
_progressValue = i * 10;
// プログレスバー更新
delegate_UpdateProgressBar callback =
new delegate_UpdateProgressBar(UpdateProgressBar);
// Invoke してメインスレッドからメソッドを呼び出す
this.progressBar1.Invoke(callback, _progressValue);
Thread.Sleep(1000);
}
}
catch (ThreadAbortException ex)
{
Console.WriteLine("スレッド強制終了!");
}
}
// プログレスバー更新処理用デリゲータ
delegate void delegate_UpdateProgressBar(int value);
// プログレスバー更新処理
private void UpdateProgressBar(int value)
{
// プログレスバー更新
this.progressBar1.Value = value;
}
}
}
|
|
|
※このページで紹介しているサンプルコードについて管理者は動作保障をいたしません※
※サンプルコードを使用する場合は、自己責任でお願いします※
|
【楽天 ランキング:フィギュア - アニメ・コミック】
|
|
|
|
このサイトはフリーソフトのMerge HTMLで作成されています。
このサイトはリンクフリーです。
|
ページの先頭に戻る |
Copyright© 2010-2015 Jun.Shiozaki All rights reserved. |
|
|
|