首先说下,.net 2.0 以后加强了安全机制, 不允许在 winform 中直接跨线程访问控件的属性. 所以除了控件所在的线程外的线程调用会抛异常
(Cross-thread operation not valid:Control 'textBox1' accessed from a thread other than the thread it was created on .)
下面进入正题:
第一种方法:
- public DomainQuery2()
- {
- InitializeComponent();
- System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;// 设置该属性 为 false
- }
这种方法很方便, 但是会有安全问题.
第二种方法:
- private delegate void FlushClient(string a); // 代理委托
- // 代理赋值方法
- private void TextboxFZ3(string str)
- {
- if (this.textBox3.InvokeRequired)
- {
- FlushClient fc = new FlushClient(TextboxFZ3);
- this.Invoke(fc, str); // 通过代理调用刷新方法
- }
- else
- {
- this.textBox3.AppendText(str + "\r\n");
- }
- }
- // 这个就是要开启线程的方法 如果要操作控件, 必须调用上面的方法
- private void FZ(object obj)
- {
- TextboxFZ3(obj);
- }
- // 点击执行
- private void button1_Click(object sender, EventArgs e)
- {
- Thread thread = new Thread(new ParameterizedThreadStart(SerchInfo));
- thread.IsBackground = true;
- thread.Start("我是子线程操作的控件赋值");
- }
我喜欢先上代码然后解释, 第一句: 代理委托, 当要操作控件的时候做一个判断, 如果是子线程要操作, 就使用代理委托操作 (这里不理解就在赋值方法那里打个断点调试),FZ 是具体操作的逻辑. 就是这么简单
这两种方法我比较赞同第二种, 虽然比第一种方法的代码多, 但是相对来说安全性也是有的.
来源: http://www.bubuko.com/infodetail-2827391.html