Need help getting info across a UI thread and another thread in C#

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I have a server application that receives information over a network and processes it. The server is multi-threaded and handles multiple sockets at time, and threads are created without my control through BeginInvoke and EndInvoke style methods, which are chained by corresponding callback functions.

I'm trying to create a form, in addition to the main GUI, that displays a ListBox item populated by items describing the currently connected sockets. So, what I'm basically trying to do is add an item to the ListBox using its Add() function, from the thread the appropriate callback function is running on. I'm accessing my forms controls through the Controls property - I.E:

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

Naturally I don't just call the function, I've tried several ways I've found here and on the web to communicate between threads, including MethodInvoker, using a delegate, in combination with Invoke(), BeginInvoke() etc. Nothing seems to work, I always get the same exception telling me my control was accessed from a thread other than the one it was created on.

Any thoughts?

回答1:

You have to call Invoke (or BeginInvoke) on the ListBox control you are accessing in order for the delegate to be called on the thread that created that control.

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


回答2:

I've always used something along these lines:

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

I also wrote a bunch of helper extension methods to... help.

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

used like this:

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


回答3:

Using BeginInvoke or Invoke should work fine. Could you post a short but complete program which demonstrates the problem? You should be able to work one up which doesn't actually need any server-side stuff - just have a bunch of threads which "pretend" to receive incoming connections.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!