线程间操作无效:从不是创建控件的线程访问它的三种方法
2016-04-28 21:34
363 查看
我们在ui线程创建的子线程操作ui控件时,系统提示错误详细信息为:
线程间操作无效: 从不是创建控件“XXX”的线程访问它。
就我知道的有三种方法,先看一下msdn的介绍:
访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
看下解决办法吧
下面的代码示例不异步执行任何工作,因此没有 DoWork 事件处理程序的实现。TextBox 控件的 Text 属性在 RunWorkerCompleted 事件处理程序中直接设置。
大家可以参考下MSDN:
如何:对 Windows 窗体控件进行线程安全调用
http://msdn.microsoft.com/zh-cn/visualc/ms171728(VS.85,printer).aspx
线程间操作无效: 从不是创建控件“XXX”的线程访问它。
就我知道的有三种方法,先看一下msdn的介绍:
访问 Windows 窗体控件本质上不是线程安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
看下解决办法吧
1、把CheckForIllegalCrossThreadCalls设置为false
2、利用委托
delegate void SetTextCallBack(string text); private void SetText(string text) { if (this.txt_a.InvokeRequired) { SetTextCallBack stcb = new SetTextCallBack(SetText); this.Invoke(stcb , new object[] { text}); } else { this.txt_a.Text = text; } } private void LoadData() { SetText("测试"); } //窗体加载时,用线程加载数据 private void Frm_ImportManager_Load(object sender, EventArgs e) { ThreadStart ts = new ThreadStart(LoadData); Thread thread = new Thread(ts); thread.Name = "LoadData"; thread.Start(); }
3、使用 BackgroundWorker控件
在应用程序中实现多线程的首选方式是使用 BackgroundWorker 组件。BackgroundWorker 组件使用事件驱动模型实现多线程。辅助线程运行 DoWork 事件处理程序,创建控件的线程运行 ProgressChanged 和 RunWorkerCompleted 事件处理程序。注意不要从 DoWork 事件处理程序调用您的任何控件。下面的代码示例不异步执行任何工作,因此没有 DoWork 事件处理程序的实现。TextBox 控件的 Text 属性在 RunWorkerCompleted 事件处理程序中直接设置。
// This event handler starts the form's // BackgroundWorker by calling RunWorkerAsync. // // The Text property of the TextBox control is set // when the BackgroundWorker raises the RunWorkerCompleted // event. private void setTextBackgroundWorkerBtn_Click( object sender, EventArgs e) { this.backgroundWorker1.RunWorkerAsync(); } // This event handler sets the Text property of the TextBox // control. It is called on the thread that created the // TextBox control, so the call is thread-safe. // // BackgroundWorker is the preferred way to perform asynchronous // operations. private void backgroundWorker1_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { this.textBox1.Text = "This text was set safely by BackgroundWorker."; }
大家可以参考下MSDN:
如何:对 Windows 窗体控件进行线程安全调用
http://msdn.microsoft.com/zh-cn/visualc/ms171728(VS.85,printer).aspx
相关文章推荐
- iOS之AFNetworking
- NOIP200301乒乓球
- 团队绩效评估计划
- 《时间之墟》
- Linux下SSH远程连接断开后让程序继续运行解决办法
- require和import的区别
- html5 原生 drag drop helloworld
- 流程图符号及流程图的例子
- Dijkstra算法介绍
- XML与DataSet的相互转换类
- mysql-存储过程案例-存储过程中创建表和修改表数据
- maven 学习---NetBeans IDE集成Maven
- git push ERROR: missing Change-Id in commit message footer
- poj 1584(凸包+点在凸多边形内+圆在凸多边形内)
- FMDB的使用
- iOS 关于枚举的使用
- 【转】Java高手真经全套书籍分享
- bzoj3932
- POJ 1251 Jungle Roads(最小生成树【简单】)
- 我的第一篇博客