C#经验积累_03.浅谈在Windows窗口跨线程使用控件遇到“线程间操作无效: 从不是创建控件“textBox1”的线程访问它”异常的处理方法

03.浅谈在Windows窗口跨线程使用控件遇到“线程间操作无效: 从不是创建控件“textBox1”的线程访问它”异常的处理方法
在使用C#进行跨线程操作窗体控件时会遇到如下图中的异常:
跨线程操作控件异常信息
异常起因:
在程序进程中windows框体处于一个独立的线程(下文称:主线程),当一个外部线程操作主线程中的控件或其他内容时,由于系统稳定性的限制不能直接进行跨线程操作的,便会出现以上异常信息。
可以通俗的如下理解:
有A,B两家公司,如果A公司需要使用B公司的专利B1,一般情况下是不能直接免费的使用B1的。如果A公司未经B公司同意使用B1就会引起B公司的反制
解决方法(以WinForm为例):
1):关闭跨线程检查
直接将窗体的CheckForIllegalCrossThreadCalls(跨线程检查)属性设置为false,默认此设置是true

    CheckForIllegalCrossThreadCalls = false;

2):使用异步上下文的方式进行跨线程操作(需要引用System.Threading;)
使用步骤:
a.获取窗体的操作线程的同步上下文
SynchronizationContext syncontext = SynchronizationContext.Current;
b.使用 SynchronizationContext 的Post函数进行异步操作
syncontext.Post(_ => {…TODO…}, null);
实例代码:

syncontext.Post(_ => { textBox1.Text = $"当前跨线程检查是否启动:{CheckForIllegalCrossThreadCalls}{Environment.NewLine}使用SynchronizationContext的post方式进行跨线程显示"; }, null);
   补充知识->Post和Send的区别:
            Post:将跨线程的进行的操作同步到主线程中,相当于 BeginInvoke
            Send:将同线程的操作同步到控件中,相当于Invoke
          实际使用中要注意区分,否则仍可能会出现跨线程异常

3):使用控件自带的异步方法
使用步骤:
a.根据控件的InvokeRequired属性来判断是否是跨线程对控件的操作(以TextBox控件为例)

      bool isCrossThreadCalls= textBox1.InvokeRequired);//是否是跨线程的,true为跨线程
b.使用控件的异步Inovke方法
textBox1.Invoke(new Action(() => { textBox1.Text = $"当前跨线程检查是否启动:{CheckForIllegalCrossThreadCalls}{Environment.NewLine}使用Invoke方式进行跨线程显示"; }));

实例代码:

if (textBox1.InvokeRequired)
  textBox1.Invoke(new Action(() => { textBox1.Text = $"当前跨线程检查是否启动:{CheckForIllegalCrossThreadCalls}{Environment.NewLine}使用Invoke方式进行跨线程显示"; }));
补充知识:
如果在主线程中使用控件的In方法会出现如下异常,因此必须要区分主线程操作和跨线程操作:

在主线程中使用控件的Inovke遇到的异常
水平有限,欢迎大家交流指正!!!
实例项目代码

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点点滴滴_每天进步一点点!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值