3流プログラマのメモ書き

元開発職→社内SE→派遣で営業支援の三流プログラマのIT技術メモ書き。 このメモが忘れっぽい自分とググってきた技術者の役に立ってくれれば幸いです。(jehupc.exblog.jpから移転中)

(.Net)サブスレッドからメインスレッドのFormを操作したい

マルチスレッドのプログラムで、重たい処理を行うサブスレッドから、フォームを操作する方法です。

調査するとフォームのコントロールはメインスレッドで動くようです。

なので、サブスレッドからそのままフォーム上のコントロールを触ると、例外が発生します。

これを回避するには下記のように、コントロールInvoke メソッドを使ってアクセスするといいようです。(C#)

private void Form1_Load(object sender, EventArgs e)

{

mTh = new Thread(new ThreadStart(ThreadMethod));

mTh.IsBackground = true;

mTh.Start();

}

 

//別スレッドで動くメソッド

private void ThreadMethod()

{

//親元のスレッドで動くフォームを操作

this.Invoke(

(MethodInvoker)delegate()

{

this.Label1.Text = "hogehoge";

});

}

参考:

別スレッドからフォームコントロールを操作するには?

@IT:.NET TIPS Windowsフォームで別スレッドからコントロールを操作するには?

C#と諸々 Windowsアプリケーションにおけるマルチスレッドの注意点 もう少し深い内容まで触れられています。

補足:

上記では、Control.Invoke メソッドを使いましたが、Control.BeginInvoke メソッドを使う方法もあるようです。

違いは、Control.Invoke メソッドが同期呼び出しになり、Control.BeginInvoke メソッドが非同期呼び出しになるようです。

どっちを使っても構わないようですが、非同期で処理する必要がないのであれば、Invokeの方が良いという意見があります。

参考:

MSDN:方法 : スレッドからコントロールを操作する

#54 Control.BeginInvokeは使ってはいけない « Visual Basic « Gab_kmのブログ

Part 1. Windows フォームのマルチスレッド処理の基礎 - とあるコンサルタントのつぶやき - Site Home - MSDN Blogs