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

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

相关推荐
逸风尊者3 分钟前
开发可掌握的知识:推荐系统
java·后端·算法
Violet_YSWY7 分钟前
阿里巴巴状态码
后端
灵魂猎手11 分钟前
Antrl4 入门 —— 使用Antrl4实现一个表达式计算器
java·后端
moxiaoran575321 分钟前
Go语言的递归函数
开发语言·后端·golang
IT 行者1 小时前
Spring Security 7.0 新特性详解
java·后端·spring
华仔啊1 小时前
Java 的金额计算用 long 还是 BigDecimal?资深程序员这样选
java·后端
秦苒&1 小时前
【C语言】详解数据类型和变量(二):三种操作符(算数、赋值、单目)及printf
c语言·开发语言·c++·c#
张人玉1 小时前
c#常用的类
服务器·数据库·c#
12344521 小时前
【MCP入门篇】从0到1教你搭建MCP服务
后端·mcp
okseekw1 小时前
Java多线程开发实战:解锁线程安全与性能优化的关键技术
java·后端