不同线程访问同一控件导致的不安全错误解决办法
2019-03-07 10:47
477 查看
WinForm不同线程访问同一控件导致的不安全错误解决办法
错误原因分析
造成这一错误的原因通常是非创建该控件的线程操作了这个控件,比如主线程创建了窗口A,分线程要关掉窗口A。因为程序并不能确定主线程是不是在操作这个窗口,所以盲目的关闭这个窗口会造成不可预料的错误!(当然,只要你逻辑清楚是不会出错的,但是编译器还是要强制进行安全检查)
解决方案
对于这个问题,最好的解决方案是通过创建该控件的进程操作这个控件,那么怎么在分线程中找到创建该控件的线程呢?答案是使用代理(委托),把分线程不能操作的方法包成代理方法,让分线程中被操作的控件执行这个代理就可以了。
代码实现
场景假设
假设通过FormA去创建FormB,之后在通过新线程去关闭FormB
FormA去创建FormB
private void button1_Click(object sender, EventArgs e)
{
FormB fb = new FormB();
fb.ShowDialog();
}
FormA创建新线程管理FormB
private void button1_Click(object sender, EventArgs e)
{
//其中closeFormMethod为你要管理控件的方法;
Thread th = new Thread( new ThreadStart(closeFormMethod) );
th.Start();
FormB fb = new FormB();
fb.ShowDialog();
}
分线程中创建代理,并用代理去执行分线程中不能执行的方法
private delegate void HideFrom();
private void closeFormMethod()
{
//延时3S是为了保证窗口B确确实实被创建了
Thread.Sleep(3000);
HideFrom hideFrom = new HideFrom(fb.Close);
fb.Invoke(hideFrom);
}
解决方案分析
这个代理方法并不是真正由分线程执行的,而是由创建控件的线程执行的,当控件调用invoke方法的时候,会通过控件的控件树找到创建这个控件的父控件,从而找到父控件中创建这个控件的线程,并由这个线程调用代理方法。从而做到线程安全。
相关文章推荐
- IE8 访问https安全证书错误;导航阻止 解决办法
- wusir 线程间操作无效: 从不是创建控件“”的线程访问它 解决办法
- “从不是创建XX控件的线程访问它”错误的解决方法!
- 关于“系统错误&H80004015(-2147467243).此类别是作为跟调用程序不同的安全ID运行的”的解决办法
- C#中加载界面时由于数据量大,导致加载很慢,可以使用MethodInvoker委托解决跨线程访问控件
- 小结“线程间操作无效: 从不是创建控件的线程访问它” 错误的解决方法
- IE8访问https链接警告安全证书错误的解决办法
- IE8 访问https安全证书错误;导航阻止 解决办法
- 小结“线程间操作无效: 从不是创建控件的线程访问它” 错误的解决方法
- IE8 访问https安全证书错误;导航阻止 解决办法 《转》
- EF(Entity Framework)发生错误”正在创建模型,此时不可使用上下文“的解决办法。 正在创建模型,此时不可使用上下文。如果在 OnModelCreating 方法内使用上下文或如果多个线程同时访问同一上下文实例,可能引发此异常。请注意不保证 DbContext 的实例成员和相关类是线程安全的。 临时解决了这个问题,在Context的构造函数中,禁用了自动初始化:
- 【转】线程间操作无效:从不是创建控件 的线程访问它,解决办法
- IE8 访问https安全证书错误;导航阻止 解决办法 《转》
- 小结“线程间操作无效: 从不是创建控件的线程访问它” 错误的解决方法
- 未从创建控件的线程访问解决办法
- 跨线程访问控件解决办法
- 线程同步锁对象不同导致的安全问题及解决办法
- C# 线程操作 出现“从不是创建控件lstUser的线程访问它”错误的解决方法
- SQL SERVER 数据库选项设置错误导致跨数库访问效率低下,及解决办法
- 小结“线程间操作无效: 从不是创建控件的线程访问它” 错误的解决方法