【问题标题】:Accessing Form Window in another thread在另一个线程中访问表单窗口
【发布时间】:2010-10-13 11:53:09
【问题描述】:

如何在另一个线程中的窗口的列表框中添加条目。 我的问题是,我必须线程。 一个工作线程完成所有实际工作,一个线程用于我想要显示状态信息的窗口。 我试图在构造函数中将表单窗口作为参数传递,但是当我调用它时出现异常。

这是我的一些代码来说明问题:

public partial class Mainform : Form
{
    private string db = String.Empty;
    private string password = String.Empty;
    private string sqlinifile = String.Empty;
    DatabaseListener dbListener;
    StatusWindow statusWindow;

    public Mainform()
    {
        //
        // The InitializeComponent() call is required for Windows Forms designer support.
        //
        InitializeComponent();

        //
        // TODO: Add constructor code after the InitializeComponent() call.
        //
        db = "EWAG";
        password = "secret";
        sqlinifile = "C:\\Programme\\Unify\\Team Developer 5.2\\sql.ini";
        textBoxDB.Text = db;
        textBoxPwd.Text = password;
        textBoxSqlIni.Text = sqlinifile;

        statusWindow = new StatusWindow();
        dbListener = new DatabaseListener(statusWindow);
    }

    public void threadStarter()
    {
        this.dbListener.startSynchronizing(5);

    }
    void Button1Click(object sender, EventArgs e)
    {
        this.db = textBoxDB.Text;
        this.password = textBoxPwd.Text;
        this.sqlinifile = textBoxSqlIni.Text;

        if (dbListener.connectToDatabase(db,"sysadm", password, sqlinifile)) 
        {
            this.Hide();
            statusWindow.Show();
            Thread synchronizer = new Thread(new ThreadStart(threadStarter));
            synchronizer.Start();

        }
    }       

}

【问题讨论】:

    标签: c# .net multithreading


    【解决方案1】:

    使用.Invoke(),卢克。

    说真的,要从另一个线程与窗体上的某些控件对话,您必须 Invoke() 一些方法,以便与窗口句柄对话的属性设置器被序列化到主 UI 线程,它是消息泵。

    或者,使用主 UI 线程上的计时器来收集信息并将它们放入列表框中。

    或使用混合方法,一个线程收集数据,将其放入未绑定到 UI 的队列中,并使用计时器将其出列并在表单上显示数据。我偶尔使用它,因为接收数据速率太大,它会阻塞 UI。

    【讨论】:

      【解决方案2】:

      使用Control.Invoke 调用任何应该触及用户界面的代码。

      【讨论】:

        【解决方案3】:

        除了使用 Invoke() 之外,检查是否需要使用要修改的对象的 InvokeRequired 属性与当前线程进行 Invoke。您可以使用下面代码中的模式创建委托并使方法线程安全。

            private delegate void LogLineDelegate(string ShortText, string LongText);
            private void LogLine(string ShortText, string LongText)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new LogLineDelegate(LogLine), new object[] { ShortText, LongText });
                    return;
                }
                sbLog.Append(string.Format("{0:MM-dd-yy} {0:HH:mm:ss.fff} - {1}: {2}.\r\n", DateTime.Now, ShortText, LongText));
                textBoxLog.Text = sbLog.ToString();
            }
        

        【讨论】:

          猜你喜欢
          • 2016-08-31
          • 1970-01-01
          • 1970-01-01
          • 2019-01-06
          • 2021-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-28
          相关资源
          最近更新 更多