- PR -

【C#(VS2003)】Contorol.Invokeメソッドの挙動について

1
投稿者投稿内容
Makoto
大ベテラン
会議室デビュー日: 2004/03/31
投稿数: 133
投稿日時: 2006-07-21 13:16
いつもお世話になっております。

下記動作に関して、ご意見をお願いします。

下記のようなコードを実行した場合には
ワーカスレッドで実行しているmsgboxDelegate処理は
画面側のスレッドで実行されると思います。
(モーダルで表示されるので、そのように動作しています。)

public class Form1 : System.Windows.Forms.Form
{
 work m_woker=null;

 private void button1_Click(object sender, System.EventArgs e)
 {
  m_woker = new work(this);
  Thread th = new Thread(new ThreadStart(m_woker.Run));
  th.IsBackground=true;
  th.Start();
 }

 public void msgbox(string msg)
 {
  MessageBox.Show(msg);
 }

 delegate void msgboxDelegate(string msg);
}

public class work
{
 Form1 m_owner=null;

 public work(Form1 owner)
 {
  m_owner=owner;
 }

 public void Run()
 {
  while(true)
  {
   System.Threading.Thread.Sleep(5000);
   Object[] args = new object[1];
   args[0] = "ワーカスレッドから画面スレッドへ処理を委譲しています。";

   m_owner.Invoke(new msgboxDelegate(m_owner.msgbox),args);

   //こっちは、ワーカスレッド上でメッセージ表示
   m_owner.msgbox((string)args[0]);
  }
 }
}

上記サンプルでは、メッセージボックスは画面上に
モーダル表示されるのでうまくInvokeできているようです。

ただ現在作成しているアプリではInvokeしても、
メッセージボックスがモーダル表示のこともあれば
モードレス表示のこともあります。
(うまくInvokeされないことがある!?)

上記サンプルと現在作成しているアプリとの違いは下記です。

サンプル :『ワーカスレッドからのInvoke』

作成アプリ:『3rdParty製のCOMオブジェクトからの通知イベント受信処理
      (COM内のスレッドからの)Invoke)』

ここで教えて頂きたいのですが、
COM(DLLをC++で実装)からの通知イベントをC#アプリで受信時、
画面へのInvokeを行った場合に、COM側のスレッド側で処理されること
があるのでしょうか?
(Invokeに失敗する?ことがあるのでしょうか?)

※例外はスローされませんし、BeginInvokeでも現象は同じです。

ちなみにやりたい処理は、『異常データ受信時にメッセージを前面に出したい』
だけです。
ただ、メインアプリがTopMost表示のため、Invoke処理がメインスレッドで
実行されないとメッセージボックスが画面裏に表示されてしまうので、
ユーザから見えないので困っています。
(この問題が回避できれば、Invokeは今のままでも別に問題ないです。)

なぜ挙動が変わるのかは気になりますが...

以上、ご意見をお願いします。
1

スキルアップ/キャリアアップ(JOB@IT)