2011-08-04 3 views
2

http://msdn.microsoft.com/en-us/library/ms171728.aspx#Y190Windowsフォーム:スレッドセーフなGUIへのアクセス?私はこのチュートリアル(最初のスレッド安全な方法)を使用していた私は、デリゲートに苦労し、Windowsがコントロール(C++)をフォームにアクセスしました最後の時間で

のTextBoxとラベルを変更する私が欲しい時に完璧に動作しますが、別のスレッドからGUI全体を表示または非表示にするには、これは失敗します。呼び出しが呼び出されている場合、句が真である最初の呼び出しで

System::Void UI::showUI(boolean value) { 
    if (this->InvokeRequired) {  
     SetTextDelegate^ d = gcnew SetTextDelegate(this, &UI::showUI); 
     this->Invoke(d, gcnew array<Object^> { value }); 
    } else { 
     if (value == true) 
      this->Show(); 
     else 
      this->Hide(); 
    } 
} 

私は(GUIクラスの一部である)は、以下のMethodeのを使用します。しかし、通常、showUIメソッドは、if節がfalseを返す場所で自動的に2回目に呼び出されるべきですが、これは起こっていません。したがって、GUIは表示も隠れもしていません。

デリゲートでGUIを表示/非表示にする必要がありますか、またはすべてのスレッドからGUIを表示できますか?デリゲートが必要な場合、なぜshowUIが2度目に実行されないのですか?

おかげで、 マーティン

編集:大丈夫

答えて

2

これは、コントロールでは珍しくないデッドロックのかなりの標準的なケースです...名前SetTextDelegateは適切ではありませんが、これはポイントではありません::呼び出し()。 UIスレッドがビジーでない場合にのみ処理を続行できます。 Debug + Windows + Threadsを使用し、メインスレッドをダブルクリックします。コールスタックを見て、それが何をしているのかを見てください。典型的なケースは、スレッドがジョブを終了するのを待っていることです。これは、スレッドがInvoke()呼び出しが戻るまで完了できないため、決して起こりません。

UIスレッドをブロックしないでください。

BackgroundWorkerを使用することを検討してください。そのRunworkerCompletedイベントは、スレッドの完了後に処理を行うのがいいです。ブロックする必要はありません。

+0

ああそれは簡単です!ありがとう、私は明日(ここではそれは11:30です)... – martin

+0

は完璧に動作します - ありがとう! – martin

関連する問題