2016-11-18 3 views
1

私は "WaitOne"をテストしたい、そして結論はUIを表示していなければ正しいです、UIのリストを表示するとき、それは間違っています。なぜ私はディスプレイ上の問題だが、私はそれを修正する方法を知らない。2つのスレッドからリストデータを確認するにはどうすればいいですか?

thd01が "Application.DoEvents()"を使用すると、thd02は機能することができますが、スレッドが戻ってthd01を続行する必要があります。

この問題を解決する方法を教えてもらえますか?

private void btn_Base_Click(object sender, EventArgs e) 
{ 
    Thread thd01 = new Thread(new ThreadStart(Base_thd1)); 
    Thread thd02 = new Thread(new ThreadStart(Base_thd2)); 

    thd01.Start(); 
    thd02.Start(); 
} 
private void Base_thd1() 
{ 
    if (list_Base.InvokeRequired) 
    { 
     BeginInvoke(new OnUpdateListInvokeDelegate1(Base_thd1)); 
    } 
    else 
    { 
     list_Base.Items.Add("Start thd1"); 

     Application.DoEvents(); 
     list_Base.Items.Add("thd1 Sleep"); 
     Thread.Sleep(3000); 
     list_Base.Items.Add("End thd1"); 

     list_Base.Items.Add("Set "); 
     mre.Set(); 
    } 
} 

private void Base_thd2() 
{ 
    if (list_Base.InvokeRequired) 
    { 
     BeginInvoke(new OnUpdateListInvokeDelegate1(Base_thd2)); 
    } 
    else 
    { 
     list_Base.Items.Add("Start thd2"); 
     list_Base.Items.Add("thd2 Wait..."); 

     mre.WaitOne() 

     list_Base.Items.Add("End thd2"); 
} 

は私がUIを表示しない場合WaitHandle.waitone、 をテストするために2つのスレッドを作成し、正しい結論は、このようなものです。

スタートは

THD1は睡眠があり、THD2プロセスがWaitOneまで実行し続けるTHD2 終了を設定しTHD1 THD1 エンド... THD1睡眠がTHD2 が待っTHD2開始 THD1。 そして、thd1が起床し、 はthd2を通信し、thd2プロセスが実行を継続できるようにします。

UIのリストを表示することができない場合は違いです。メインスレッドを検討する必要があります。

最初にメインスレッドを呼び出すと、UIのリストを表示できるようになりますが、ブレークポイントが必要です。したがって、 'Application.DoEvents()'を使用すると、thd1がスリープしても動作し続けます。

しかし、thd1を返すことはできません。

フローチャート: thd1 ->(OK) thd2 ->(How to do.) thd1

+0

達成したいことをもう少し明確にできますか?スレッド1が動作している間、thread1が待機している間にthread2が何らかの操作を行うなど、何が起こるべきかについて少し詳しく説明します。 – smartobelix

+1

ああ、良い古い 'Application.DoEvents()' hack ... –

答えて

1

あなたはそれが.InvokeRequired()をテストすることによって、GUIスレッド(で実行されるかどうかを確認する新しいスレッドを開始することは、常に最初の呼び出しになりますケース()だ場合はBeginInvoke()呼び出します。これはGUIスレッド上であなたのメソッドを呼び出すように待ち行列に入れます。そして、あなたが正しいスレッド上にいるかどうかを再度テストするGUIスレッド内でメソッドが2回呼び出されると、 GUIスレッドからのリスト

つまり、あなたのThread.Sleep()とあなたのGUIスレッド内でリストの記入が呼び出されます。作成されたすべてのスレッドは、呼び出しをGUIスレッドに転送して終了します。

private void Base_thd1() 
{ 
    BeginInvoke(new Action(() => list_Base.Items.Add("Start thd1"))); 
    Thread.Sleep(3000); 
    BeginInvoke(new Action(() => list_Base.Items.Add("End thd1"))); 
    BeginInvoke(new Action(() => list_Base.Items.Add("Set "))); 
    BeginInvoke(new Action(() => mre.Set())); 
} 

たぶん、あなたはBackgroundWorkerを見てみる必要があります。

ただ、最初のモックのために、あなたはこのような何かにあなたの方法を書き換える必要があります。別のスレッドでコードを実行し、そのメソッド内でReportProgress()を呼び出すと、GUIスレッドでProgressChangedにアタッチされたメソッドを実行します。また、メソッドが終了した後、RunWorkerCompletedにアタッチされたメソッドをGUIスレッド内で呼び出します。

関連する問題