写C/S程序的时候经常遇到一个线程中操作另一个线程的控件,比如当收到消息的时候在RICHTEXTBOX增加内容。在不同的测试环境下,可能产生不同的异常,我用vs2003的时候,没有什么提示,就是操作不是每次都成功,在vs2005下会引发一个异常[有些朋友的VS2003也会],提示“从不是创建控件的线程访问它”。这跟现实中的一些例子是一样的,例如取款机,如果你不是银行的负责人,只能用卡,如果你去开锁,那么一会警察就来了。那怎么在一个线程中操作另一个线程的控件呢?
比较常用的就是使用委托(delegate)来完成,不知道委托的可以搜索C#睡前故事,如:http://www.google.com/search?q=C%23%E7%9D%A1%E5%89%8D%E6%95%85%E4%BA%8B&hl=zh-CN&newwindow=1&lr=lang_zh-CN%7Clang_zh-TW&nxpt=20.640385052413339671421 ,VS2005 WINFORM 控件都有了一个 InvokeRequired 属性,如果属性为true 说明其他线程正在操作该控件,这时就要创建一个委托实例,然后调用控件对象的 Invoke 方法,保证其他现成可以安全操作本线程中的控件。例如
比较常用的就是使用委托(delegate)来完成,不知道委托的可以搜索C#睡前故事,如:http://www.google.com/search?q=C%23%E7%9D%A1%E5%89%8D%E6%95%85%E4%BA%8B&hl=zh-CN&newwindow=1&lr=lang_zh-CN%7Clang_zh-TW&nxpt=20.640385052413339671421 ,VS2005 WINFORM 控件都有了一个 InvokeRequired 属性,如果属性为true 说明其他线程正在操作该控件,这时就要创建一个委托实例,然后调用控件对象的 Invoke 方法,保证其他现成可以安全操作本线程中的控件。例如
delegate void AppendStrDg(string str);
private void AppendStr(string str){
if(RichTextBox1.InvokeRequired){
AppendStrDg dg = new AppendStrDg(AppendStr);
RichTextBox1.Invoke(dg,"user->:Hello World!");
} else{
RichTextBox1.Text += str;
}
}
其实我们不用判断也知道该控件是哪个线程创建的,因为程序是你自己写的,当然清楚是UI线程创建的还是其他方法创建的。
private void AppendStr(string str){
if(RichTextBox1.InvokeRequired){
AppendStrDg dg = new AppendStrDg(AppendStr);
RichTextBox1.Invoke(dg,"user->:Hello World!");
} else{
RichTextBox1.Text += str;
}
}