【问题标题】:Update WinForm Controls from another thread _and_ class从另一个线程 _and_ 类更新 WinForm 控件
【发布时间】:2012-08-27 12:12:25
【问题描述】:

我正在制作一个 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
}

我知道事件处理程序可能是要走的路,但我不知道在这种情况下如何做(我也愿意接受其他建议;))

任何帮助表示赞赏

【问题讨论】:

    标签: c# winforms multithreading class controls


    【解决方案1】:

    从哪个类更新表单并不重要。 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' 没有通过。

    【讨论】:

    • 这很好,但是它涉及将“this”作为参数传递,并且我一直认为如果你必须这样做,你的程序结构就会很糟糕。不过我可能完全错了:)
    • 你是对的,将'this'作为参数传递不是一个好主意。在这里,您没有传递“this”。请查看更新后的答案。
    • 看起来不错,谢谢,但还有一个问题:“...您确实必须获得对 WinForm:Form 对象的引用。”
    • 是的。如果类 clientConnection 需要更新一个 winForm 对象,它必须能够引用它。一种选择是在 clientConnection 对象的构造过程中传递对 winForm 对象的引用,clientConnection 对象可以存储它。
    • 这仍然意味着我必须将'this'传递给'Server',但只有一个实例,所以我想这并不重要:L
    【解决方案2】:

    你可以使用 backgroundworker 来创建你的其他线程, 它使您可以轻松地处理您的 GUI

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

    【讨论】:

      猜你喜欢
      • 2013-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多