一、简述

C#中不允许跨线程直接访问界面控件,即一个线程中如主线程创建的控件不允许被其他线程例如子线程直接访问,如果直接访问或设置属性则会爆出“调用线程无法访问此对象,因为另一个线程拥有该对象”等类似错误。
在一个线程中设置其他线程所有的控件属性通常有两种方法,一是设置System.Windows.Forms.Control的CheckForIllegalCrossThreadCalls属性值为false,表示不对错误线程的调用进行捕捉,这种方法只对winforms界面框架有效,在WPF中无法设置该属性,只能使用第二种方法。
第二种方法是通过委托来实现控件属性设置,需要通过InvokeBeginInvoke来实现,Invoke表示同步,BeginInvoke表示异步,下面列举了在winforms中和WPF两种界面框架中跨线程访问控件的代码示例。

二、Winforms中跨线程访问控件

一般的委托方法示例代码如下:

delegate void delegateSetText(string str);//定义一个委托
private void SetText(string str)
{
  if (InvokeRequired)//判断是否是被其他线程调用
{
delegateSetText delegatesetText01 = new delegateSetText(SetText);
Invoke(delegatesetText01, new object [] {str});
return;
}
textBox01.Text = str;
}

也可以采用匿名代理的方式,示例代码如下:

delegate void delegateSetText(string str);//定义一个委托
private void SetText(string str)
{
  delegateSetText delegatesetText01 = delegate(string str01)
{
textBox01.Text = str01;
}
Invoke(delegatesetText01, new object [] {str});
}

三、WPF中跨线程访问控件

在WPF中跨线程访问控件需要使用Dispatcher。Dispatcher是WPF中的线程调度管理器,用在子线程刷新主线程(UI线程)(比如绑定的时候,属性更新的时候),在子线程里面起一个dispatcher,将工作项目调度到 UI 线程,让主线程调度刷新UI的代码。示例代码如下:

private void SetText(string str)
{
  if (!Dispatcher.CheckAccess())//判断是否是被其他线程调用
{
Dispatcher.Invoke(() => SetText(str));
return;
}
textBox01.Text = str;
}
 
【注】

避免”在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。“错误。

一个Form窗体必须完全创建完成,才能调用它自身或它上面控件的Invoke或BeginInvoke。

经测试,窗体的构造函数内的InitializeComponent()的执行完成时,窗体并未创建完成;窗体的构造函数执行完成时,窗体也并未创建完成;

在form.show()后,窗体是已经创建完成了。

另外,可以在调用Invoke()前,判断一下 if (form.Created),以避免此处异常中断。

参考文档

C#中Invoke的用法()
不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改
【C#】调用线程无法访问此对象,因为另一个线程拥有该对象
InvokeRequired和Invoke
InvokeRequired in wpf [duplicate]
C# 跨线程调用TextBox方法浅析 利用SetTextCallback方法

转自 https://blog.csdn.net/weixin_46846685/article/details/113956491?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-113956491-blog-125960916.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6-113956491-blog-125960916.pc_relevant_recovery_v2&utm_relevant_index=10

最新文章

  1. win10常用帮助
  2. Jquery ajax 学习笔记
  3. [Codevs 1421]秋静叶&秋穣子(最大-最小博弈)
  4. [转]基于gulp和webpack的前端工程化
  5. svn使用方法介绍(1)
  6. [CareerCup] 9.11 Parenthesize the Expression 表达式加括号
  7. [saiku] 免登陆进入管理后台
  8. Android模拟器分辨率介绍
  9. 关于typedef的用法总结
  10. Android 手机上安装并运行 Ubuntu 12.04(转,没实测)
  11. JavaScript es2015经验基础总结
  12. PTA题目的處理(四)
  13. Floyd算法解决多源最短路问题
  14. js初学
  15. python模块_hashlib详解
  16. php 从1加到100
  17. 在网页浏览器中原生显示PDF文件
  18. K8s集群安装和检查(经验分享)
  19. ubuntu下tensorflow安装
  20. Linux建立互信关系(ssh公钥登录)

热门文章

  1. Zstack EPICS Archiver在小课题组的使用经验
  2. 安卓逆向 JNI实先java与C互通
  3. 部署Kubernetes v1.22.10高可用集群
  4. rin和快速迭代
  5. Docker安装配置Oracle详细教程(以作持久化处理)
  6. Net6 Core Api(.net6)发布到IIS注意事项及显示HTTP 错误500.19解决方法
  7. vue+html5实现上传图片
  8. MySQL单节点变更为主从节点
  9. docker 安装 jFrog
  10. 增加select的option之间的间距