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

时间:2012-08-26 15:42:03

标签: c# winforms multithreading class controls

我正在制作一个WinForms程序,它需要单独的线程 为了便于阅读和维护,我将所有非GUI代码分成不同的类。这个类还“生成”另一个类,它进行一些处理。但是,我现在遇到了一个问题,我需要从一个在不同类中启动的线程更改WinForms控件(将字符串附加到文本框)

我已经四处搜索,找到了不同线程的解决方案,并且在不同的类中,但不是两者都有,并且所提供的解决方案似乎与我不兼容

然而,这可能是最大的“领先”:How to update UI from another thread running in another class

类层次结构示例:

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 个答案:

答案 0 :(得分:11)

您要更新表单的类别无关紧要。 WinForm控件必须在创建它们的同一个线程上更新。

因此,Control.Invoke允许您在自己的线程上对控件执行方法。这也称为异步执行,因为调用实际上是排队并单独执行的。

看看这个article from 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'未通过。

答案 1 :(得分:-1)

你可以使用backgroundworker制作你的其他帖子, 它允许您轻松处理您的GUI

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