C# 在另一个线程中访问窗体窗口
如何在另一个线程中的窗口的列表框中添加条目。 我的问题是,我必须要有线程。 一个工作线程,完成所有实际工作,一个线程用于显示状态信息的窗口。 我试图在构造函数中将窗体窗口作为参数传递,但是当我调用它时,我得到了一个异常 下面是我的一些代码来说明这个问题:C# 在另一个线程中访问窗体窗口,c#,.net,multithreading,C#,.net,Multithreading,如何在另一个线程中的窗口的列表框中添加条目。 我的问题是,我必须要有线程。 一个工作线程,完成所有实际工作,一个线程用于显示状态信息的窗口。 我试图在构造函数中将窗体窗口作为参数传递,但是当我调用它时,我得到了一个异常 下面是我的一些代码来说明这个问题: public partial class Mainform : Form { private string db = String.Empty; private string password = String.Empty;
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();
}
}
}
使用Luke的.Invoke()
说真的,要从另一个线程与窗体上的某些控件进行对话,您必须Invoke()
某些方法,以便与窗口句柄对话的属性设置器被序列化到主UI线程及其消息泵
或者,使用主UI线程上的计时器收集信息并将其放入列表框
或者使用混合方法,一个线程收集数据,将其放入未绑定到UI的队列中,然后使用计时器将其出列并在表单上显示数据。我偶尔使用它,因为接收数据的速率太大,会阻塞用户界面。使用.Invoke()
,Luke
说真的,要从另一个线程与窗体上的某些控件进行对话,您必须Invoke()
某些方法,以便与窗口句柄对话的属性设置器被序列化到主UI线程及其消息泵
或者,使用主UI线程上的计时器收集信息并将其放入列表框
或者使用混合方法,一个线程收集数据,将其放入未绑定到UI的队列中,然后使用计时器将其出列并在表单上显示数据。我偶尔使用它,因为接收数据速率太大,它会阻塞UI。用于调用任何应该接触UI的代码。用于调用任何应该接触UI的代码。除了使用Invoke(),检查是否需要使用要修改的对象的invokererequired属性调用当前线程。您可以使用下面代码中的模式创建委托并使方法线程安全
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();
}
除了使用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();
}