在另一个线程中访问表单窗口

时间:2010-10-13 11:53:10

标签: c# .net multithreading

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

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

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();

        }
    }       

}

4 个答案:

答案 0 :(得分:4)

使用.Invoke(),Luke。

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

答案 3 :(得分:0)

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

    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();
    }