在看别人代码的时候老是会Invoke和BeginInvoke方法,虽然大体明白是什么意思,但却不能很好的使用,上网查了不少资料,刚巧看到本身求学期间转载过一篇博文:html
博文中讲的都是一些理论知识,本文介绍几个常见的问题:异步
.net平台下Winform、wpf禁止跨线程直接访问控件,所以在必须跨线程访问控件的时候采用异步方式。socket
一、winform项目中跨线程访问控件:ui
编写一个Winform小实例:在作winform项目中,有时为了将系统运行的状态实时显示到Form中,所以添加一个RichTextbox控件实时显示系统运行日志。本例实现的操做是将日志以字符串的形式写入RichTextbox控件,由于是实时显示,因此涉及到跨线程输入的问题。this
private delegate void setRichTexBox(string s); public void setText(string txt) { if (this.t_revmsg.InvokeRequired)//等待异步 { setRichTexBox fc = new setRichTexBox(Set); this.Invoke(fc, new object []{ txt}); } else { this.t_revmsg.AppendText(txt); } }
private void Set(string txt) { t_revmsg.AppendText(txt); }
控件的InvokeRequired的值为true时,说明有一个不属于建立它的线程要访问它,此时须要采用异步的方式进行操做。spa
能够改进:.net
private delegate void setRichTexBox(string s); public void SetText(string txt) { if (this.tbReceiveMsg.InvokeRequired)//等待异步 { setRichTexBox fc = new setRichTexBox(SetText); this.Invoke(fc, new object[] { txt }); } else { this.tbReceiveMsg.AppendText(txt); } }
二、wpf项目中跨线程访问控件:线程
wpf的page页中,加入一个button控件和textbox控件,点击button实现添加textbox控件中的内容。日志
private void button2_Click(object sender, RoutedEventArgs e) { this.textBox1.Dispatcher.Invoke(new WriteDelegate(WriteMethod), "asdf"); } private delegate void WriteDelegate(string str); private void WriteMethod(string str) { this.textBox1.AppendText(str); }
三、wpf项目中跨线程获取textbox控件中的内容
本实例实现的功能是:点击button控件,开启socket监听服务。监听的端口须要从UI界面中的textbox中获取,由于不是建立它的线程访问它,所以才有Dispatcher.Invoke异步操做。稍做补充:在开启监听的过程当中,有while(true)死循环,将其直接放入到主线程都会致使线程没法正常进行下去,解决方法是开启一个新的线程来开启监听。
private void button1_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(new ThreadStart(StartServer)); thread.Start(); } public void StartServer() { int port = Convert.ToInt32(GetText(this.tbPort)); ServerSocket serverSocket = new ServerSocket(port); serverSocket.Start(); } private delegate string GetTextHandle(Control control); private string GetText(Control control) { if (this.Dispatcher.Thread != System.Threading.Thread.CurrentThread) { return (string)this.Dispatcher.Invoke(new GetTextHandle(this.GetText), control); } else { if (control.GetType() == typeof(TextBox)) { return ((TextBox)control).Text; } else { return string.Empty; } } }
总结:
由上述几个实例能够看到跨线程调用须要使用Invoke和BeginInvoke(暂时没有用到),在一些要求并非很严格的系统中,暂且认为两者是能够通用的。(不知道对不?望高手指点一二)
目前为止,所接触到的常见问题只有这些,之后遇到再补充吧。