从另一个线程和类更新WinForm控件

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
}

我知道事件处理程序可能是解决问题的方法,但在这种情况下我无法弄清楚如何实现(我也欢迎其他建议;)。
任何帮助都将不胜感激。
2个回答

11
无论从哪个类更新表单都无所谓,但WinForm控件必须在创建时的同一线程上进行更新。因此,Control.Invoke允许您在控件自己的线程上执行方法。这也称为异步执行,因为调用实际上是排队并分别执行的。查看来自msdn的文章,其中的示例与您的示例类似。一个单独的类在一个单独的线程上更新窗体上的列表框。
----- 更新 在此处不需要将this作为参数传递。在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'。

您说得对,将“this”作为参数传递不是一个好主意。在这里,您没有传递“this”。请查看更新的答案。 - shr
是的。如果类clientConnection需要更新一个winForm对象,它必须能够引用它。一种选择是在构造clientConnection对象时传递对winForm对象的引用,然后clientConnection对象可以存储它。 - shr
这仍然意味着我必须将“this”传递给“Server”,但只会有一个此实例,所以我想这并不太重要:L - LordAro
这基本上是一个设计问题。如何在系统中连接各种对象是一个关键的设计决策。有几种标准的设计模式可以提供帮助。 - shr
有几种标准的设计模式可以帮助解决这个问题。 <-- 哦?链接在哪里? :L - LordAro
显示剩余3条评论

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接