需要帮助在UI线程和C#中的另一个线程获取信息

我有一个服务器应用程序,通过网络接收信息并进行处理。 服务器是multithreading的,并且一次处理多个套接字,并且通过BeginInvoke和EndInvoke样式方法在没有我控制的情况下创建线程,这些方法由相应的回调函数链接。

我正在尝试创建一个表单,除了主GUI之外,它还显示一个ListBox项目,该项目由描述当前连接的套接字的项目填充。 所以,我基本上要做的是使用其Add()函数向ListBox添加一个项目,从该线程运行相应的回调函数。 我通过Controls属性访问我的表单控件 – IE:

(ListBox)c.Controls["listBox1"].Items.Add(); 

当然我不只是调用函数,我已经尝试了几种方法,我在这里和网上在线程之间进行通信,包括MethodInvoker ,使用delegate ,结合Invoke()BeginInvoke()等。似乎工作,我总是得到相同的exception告诉我我的控件是从一个线程访问,而不是它创建的线程。

有什么想法吗?

您必须在要访问的ListBox控件上调用Invoke(或BeginInvoke),以便在创建该控件的线程上调用委托。

 ListBox listBox = c.Controls["listBox1"] as ListBox; if(listBox != null) { listBox.Invoke(...); } 

我总是沿着这些方向使用一些东西:

  c =  if (c.InvokeRequired) { c.BeginInvoke((MethodInvoker)delegate { //do something with c }); } else { //do something with c } 

我还写了一堆辅助扩展方法来帮助。

 using System; using System.ComponentModel; public static class CrossThreadHelper { public static bool CrossThread(this ISynchronizeInvoke value, Action action, T sender, R e) { if (value.InvokeRequired) { value.BeginInvoke(action, new object[] { sender, e }); } return value.InvokeRequired; } } 

像这样使用:

  private void OnServerMessageReceived(object sender, ClientStateArgs e) { if (this.CrossThread((se, ev) => OnServerMessageReceived(se, ev), sender, e)) return; this.statusTextBox.Text += string.Format("Message Received From: {0}\r\n", e.ClientState); } 

使用BeginInvoke或Invoke应该可以正常工作。 你能发一个简短而完整的程序来certificate这个问题吗? 你应该能够工作一个实际上并不需要任何服务器端的东西 – 只需要一堆“假装”接收传入连接的线程。