3

別々のスレッドを必要とするWinFormsプログラムを作成しています。読みやすさと保守性のために、すべての非GUIコードを異なるクラスに分けています。このクラスはまた、いくつかの処理を行う別のクラスを「生成」します。ただし、別のクラスで開始されたスレッドからWinFormsコントロールを変更する(テキストボックスに文字列を追加する)必要があるという問題が発生しました。

私は周りを検索し、さまざまなスレッドとさまざまなクラスのソリューションを見つけましたが、両方ではなく、提供されたソリューションは(私には)互換性がないようです

ただし、これは最大の「リード」である可能性があります。別のクラスで実行されている別のスレッドからUIを更新する方法

クラス階層の例:

class WinForm : Form
{
    ...
    Server serv = new Server();
}

// Server is in a different thread to winform
class Server
{
    ...
    ClientConnection = new ClientConnection();
}

// Another new thread is created to run this class
class ClientConnection
{
    //Want to modify winform from here
}

私はイベントハンドラーがおそらく行く方法であることを理解していますが、私はこの状況でそうする方法を理解することができません(私は他の提案にもオープンです;))

助けていただければ幸いです

4

2 に答える 2

11

フォームを更新するクラスは関係ありません。WinFormコントロールは、作成されたのと同じスレッドで更新する必要があります。

したがって、Control.Invokeを使用すると、独自のスレッドでコントロールに対してメソッドを実行できます。これは非同期実行とも呼ばれます。これは、呼び出しが実際にはキューに入れられ、別々に実行されるためです。

msdnからのこの記事を見てください、例はあなたの例に似ています。別のスレッドの別のクラスは、フォームのリストボックスを更新します。

-----更新ここでは、これをパラメーターとして渡す必要はありません。

Winformクラスには、コントロールを更新できるパブリックデリゲートがあります。

class WinForm : Form
{
   public delegate void updateTextBoxDelegate(String textBoxString); // delegate type 
   public updateTextBoxDelegate updateTextBox; // delegate object

   void updateTextBox1(string str ) { textBox1.Text = str1; } // this method is invoked

   public WinForm()
   {
      ...
      updateTextBox = new updateTextBoxDelegate( updateTextBox1 ); // initialize delegate object
    ...
    Server serv = new Server();

}

ClientConnectionオブジェクトから、WinForm:Formオブジェクトへの参照を取得する必要があります。

class ClientConnection
{
   ...
   void display( string strItem ) // can be called in a different thread from clientConnection object
   {
         Form1.Invoke( Form1.updateTextBox, strItem ); // updates textbox1 on winForm
   }
}

上記の場合、「this」は渡されません。

于 2012-08-26T16:25:45.987 に答える
-1

あなたは他のスレッドを作るためにbackgroundworkerを使うことができます、それはあなたがあなたのGUIを簡単に扱うことを可能にします

http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

于 2012-08-26T16:17:43.337 に答える