C# 中跨线程访问控件

一、简述

C#中不允许跨线程直接访问界面控件,即一个线程中如主线程创建的控件不允许被其他线程例如子线程直接访问,如果直接访问或设置属性则会爆出"调用线程无法访问此对象,因为另一个线程拥有该对象"等类似错误。

在一个线程中设置其他线程所有的控件属性通常有两种方法,一是设置System.Windows.Forms.Control的CheckForIllegalCrossThreadCalls属性值为false,表示不对错误线程的调用进行捕捉,这种方法只对winforms界面框架有效,在WPF中无法设置该属性,只能使用第二种方法。

第二种方法是通过委托来实现控件属性设置,需要通过InvokeBeginInvoke来实现,Invoke表示同步,BeginInvoke表示异步,下面列举了在winforms中和WPF两种界面框架中跨线程访问控件的代码示例。

二、Winforms中跨线程访问控件

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

csharp 复制代码
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;
}

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

csharp 复制代码
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的代码。示例代码如下:

csharp 复制代码
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),以避免此处异常中断。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:CastleWu

出处:cnblogs.com/castlewu/p/17168964.html

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!

相关推荐
冰茶_2 小时前
WPF之绑定模式深入
学习·microsoft·微软·c#·wpf·绑定模式
西京刀客2 小时前
Go多服务项目结构优化:为何每个服务单独设置internal目录?
开发语言·后端·golang
李匠20243 小时前
C++GO语言微服务之gorm框架操作MySQL
开发语言·c++·后端·golang
源码云商3 小时前
基于Spring Boot + Vue的高校心理教育辅导系统
java·spring boot·后端
钢铁男儿3 小时前
C# 方法(参数数组)
java·算法·c#
黄俊懿4 小时前
【深入理解SpringCloud微服务】手写实现一个微服务分布式事务组件
java·分布式·后端·spring·spring cloud·微服务·架构师
惊鸿醉5 小时前
Unity C# 中的 反射 小记
unity·c#·游戏引擎
Themberfue5 小时前
RabbitMQ ②-工作模式
开发语言·分布式·后端·rabbitmq
极小狐5 小时前
如何使用极狐GitLab 软件包仓库功能托管 helm chart?
java·linux·服务器·数据库·c#·gitlab·maven
有梦想的攻城狮5 小时前
spring中的@Inject注解详情
java·后端·spring·inject