ワーカースレッドからWindowsコントロールのプロパティをいじりたいとき

ワーカースレッドループ中で
Windowsフォームのコントロールのプロパティをいじくると
たとえば、ラベルのTextプロパティに文字を突っ込んだり


有効ではないスレッド間の操作:
コントロールが作成されたスレッド以外のスレッドからコントロール ‘label1’ がアクセスされました。

なんて、エラーが出ちゃいます

Windowsコントロールのプロパティ操作や、メソッド呼び出しは
主スレッド行うのが原則で
他のスレッドからの、操作は動作保証しない感じ

でも、やっぱり、ワーカースレッドから
コントロールのプロパティ、いじりたいと思うのは、人情

そのときは、Control.Invokeメソッドを使うことにより
スレッド間の処理調停をうまい具合にやってくれます

サンプルは以下のように…
今回は、スレッドタイマークラスを使ってみました


public partial class Form1 : Form
{
private System.Threading.Timer m_tmr; //スレッドタイマ
private bool fl = true; //スレッド管理フラグ
public Form1()
{
InitializeComponent();
TimerCallback timerDelegate = new TimerCallback(TmrLabelText); //スレッドタイマのインスタンス生成
m_tmr = new System.Threading.Timer(timerDelegate, null , 0, 50);
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
fl = false; //後始末

for(int i = 0; i < 100; i++) //イベントが貯まっている可能性があるので
{
Application.DoEvents();
Thread.Sleep(1);
}

}

//---------------------------------------------
//スレッドタイマを利用したテキストの文字列代入
//
//---------------------------------------------
public void TmrLabelText(object o)
{
if (fl == true)
{
MySetControlText(label1, "aaa"); //デリゲート本体を呼び出す
}
}

//-------------------------------------------
//ラベル向け文字列セットデリゲート
//
//-------------------------------------------
private void MySetControlText(Label l, string t)
{
if (l.InvokeRequired == true)
{
deli_MySetControlText d = new deli_MySetControlText(MySetControlText);
this.Invoke(d, new object[] {l, t});
}
else
{
l.Text = t;
}
}

delegate void deli_MySetControlText(Label l, string t); //デリゲート型の定義
}
[/csharp]

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください