C#中跨线程访问控件的实现方法

 更新时间:2024年12月10日 08:28:35   作者:小码编匠  
C#中不允许跨线程直接访问界面控件,即一个线程中如主线程创建的控件不允许被其他线程例如子线程直接访问,在一个线程中设置其他线程所有的控件属性通常有两种方法,本文将详细的给大家介绍一下,需要的朋友可以参考下

一、简述

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#中跨线程访问控件的方法的文章就介绍到这了,更多相关C#跨线程访问控件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#递归实现回文判断算法

    C#递归实现回文判断算法

    这篇文章主要介绍了C#递归实现回文判断算法,方法简单实用,需要的朋友可以参考下
    2014-10-10
  • C#中使用反射获取结构体实例及思路

    C#中使用反射获取结构体实例及思路

    一般用反射获取类对象的实例比较简单,只要类有一个无参构造函数或没有显示声明带参的构造函数即可使用
    2013-10-10
  • C#通过属性名称获取(读取)属性值的方法

    C#通过属性名称获取(读取)属性值的方法

    本文主要介绍了C#通过属性名称获取(读取)属性值的方法,并提供了简化版代码,具有很好的参考价值,需要的朋友可以看下
    2016-12-12
  • c#预处理指令分析

    c#预处理指令分析

    这篇文章主要介绍了c#预处理指令的相关资料,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-08-08
  • 微信服务号推送模板消息接口

    微信服务号推送模板消息接口

    这篇文章主要介绍了微信服务号推送模板消息接口,需要的朋友可以参考下
    2015-08-08
  • c#中禁用windows的任务管理器的方法

    c#中禁用windows的任务管理器的方法

    这篇文章主要介绍了c#中禁用windows的任务管理器的方法,通过注册表实现禁用,需要的朋友可以参考下
    2014-06-06
  • 解决WPF附加属性的Set函数不调用的问题

    解决WPF附加属性的Set函数不调用的问题

    这篇文章介绍了解决WPF附加属性的Set函数不调用的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中如何正确的使用字符串String

    C#中如何正确的使用字符串String

    这篇文章主要给大家介绍了关于在C#中如何正确的使用字符串String的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • C# GUID ToString的使用总结

    C# GUID ToString的使用总结

    这篇文章主要介绍了C# GUID ToString的使用总结,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下
    2021-02-02
  • C#验证码问题的快速解决方法

    C#验证码问题的快速解决方法

    下面小编就为大家带来一篇C#验证码问题的快速解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07

最新评论