如何从C#中的另一个线程更新GUI上的文本框[复制]
参见英文答案 >
How to update the GUI from another thread in C#?44
我是C#的新手,我正在尝试制作一个简单的客户端服务器聊天应用程序. 我的客户端窗体中有RichTextBox,我正在尝试从另一个类中的服务器更新该控件.当我尝试这样做时,我得到错误:“跨线程操作无效:控制textBox1从一个线程以外的线程而被创建”. 这里我的Windows窗体的代码: private Topic topic; public RichTextBox textbox1; bool check = topic.addUser(textBoxNickname.Text,ref textbox1,ref listitems); 主题类: public class Topic : MarshalByRefObject { //Some code public bool addUser(string user,ref RichTextBox textBox1,ref List<string> listBox1) { //here i am trying to update that control and where i get that exception textBox1.Text += "Connected to server... n"; } 那怎么办呢?如何从另一个线程更新文本框控件? 我试图使用.net远程处理使一些基本的聊天客户端/服务器应用程序. 不幸发表我的整个代码,将尽可能保持简单. 服务器: namespace Test { [Serializable] public class Topic : MarshalByRefObject { public bool AddUser(string user,RichTextBox textBox1,List<string> listBox1) { //Send to message only to the client connected MethodInvoker action = delegate { textBox1.Text += "Connected to server... n"; }; textBox1.BeginInvoke(action); //... return true; } public class TheServer { public static void Main() { int listeningChannel = 1099; BinaryServerFormatterSinkProvider srvFormatter = new BinaryServerFormatterSinkProvider(); srvFormatter.TypeFilterLevel = TypeFilterLevel.Full; BinaryClientFormatterSinkProvider clntFormatter = new BinaryClientFormatterSinkProvider(); IDictionary props = new Hashtable(); props["port"] = listeningChannel; HttpChannel channel = new HttpChannel(props,clntFormatter,srvFormatter); // Register the channel with the runtime ChannelServices.RegisterChannel(channel,false); // Expose the Calculator Object from this Server RemotingConfiguration.RegisterWellKnownServiceType(typeof(Topic),"Topic.soap",WellKnownObjectMode.Singleton); // Keep the Server running until the user presses enter Console.WriteLine("The Topic Server is up and running on port {0}",listeningChannel); Console.WriteLine("Press enter to stop the server..."); Console.ReadLine(); } } } } Windows窗体客户端: // Create and register a channel to communicate to the server // The Client will use the port passed in as args to listen for callbacks BinaryServerFormatterSinkProvider srvFormatter = new BinaryServerFormatterSinkProvider(); srvFormatter.TypeFilterLevel = TypeFilterLevel.Full; BinaryClientFormatterSinkProvider clntFormatter = new BinaryClientFormatterSinkProvider(); IDictionary props = new Hashtable(); props["port"] = 0; channel = new HttpChannel(props,srvFormatter); //channel = new HttpChannel(listeningChannel); ChannelServices.RegisterChannel(channel,false); // Create an instance on the remote server and call a method remotely topic = (Topic)Activator.GetObject(typeof(Topic),// type to create "http://localhost:1099/Topic.soap" // URI ); private Topic topic; public RichTextBox textbox1; bool check = topic.addUser(textBoxNickname.Text,textBox1,listitems); 解决方法
您需要使用BackgroundWorker或Control.Invoke / BeginInvoke.匿名函数 – 匿名方法(C#2.0)或lambda表达式(C#3.0)使之比以前更容易.
在您的情况下,您可以将代码更改为: public bool AddUser(string user,List listBox1) { MethodInvoker action = delegate { textBox1.Text += "Connected to server... n"; }; textBox1.BeginInvoke(action); } 需要注意的几件事情 >为了符合.NET约定,这应该称为AddUser 有关此和其他线程主题的更多信息,请参阅my threading tutorial或Joe Albahari’s one. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |