c# 线程间操作无效—从不是创建控件的线程访问它,解决办法

一、问题原因

  C#中的线程间操作无效错误通常是由于在非创建控件的线程上访问控件引发的这是因为UI控件只能在创建它们的线程上进行访问和操作,否则会引发异常。
  问题的根源是在多线程应用程序中,当一个线程尝试访问或修改UI控件时,如果该线程不是创建控件的线程,就会引发线程间操作无效错误。

二、解决办法

1、方法1,不检查线程间操作

不检查线程间操作

CheckForIllegalCrossThreadCalls = false;      //不检查线程间操作(如果程序抛出了“线程间操作无效”异常,可以添加该行代码)
 public KUKA_TCP_SERVER(){InitializeComponent();CheckForIllegalCrossThreadCalls = false;}

2、方法2,使用Invoke方法

  解决这个问题的一种常见方法是使用Invoke或BeginInvoke方法来将操作委托给创建控件的线程执行。这样可以确保UI控件的访问和操作在正确的线程上进行。

Thread txThread = new Thread(() =>
{writeMessage("haha");
});
txThread.Start();private void writeMessage(string text)
{if (textBox1.InvokeRequired){Action<string> action = new Action<string>(SetText);Invoke(action, new object[] { text });}else{textBox1.Text = text;}
}
 /// <summary>/// TCP放在后台线程/// </summary>private void OpenTCP(){ThreadStart TCPDelegate = new ThreadStart(TCPListen);   //新建一个委托线程tcpDelegate = new Thread(TCPDelegate);                  //实例化新线程tcpDelegate.Start();}/// <summary>/// 创建TCPServer并监听/// </summary>public void TCPListen(){var listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);     //初始化 Socket 实例,该 Socket 只用于绑定本地终结点并接受客户端连接listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);        //允许 Socket 被绑定在已使用的地址上try{localEP = new IPEndPoint(IPAddress.Parse(ipaddress), setPort);                              //初始化本地终结点实例listener.Bind(localEP);                //绑定listener.Listen(10);                   //监听Print("开始监听");listener.BeginAccept(new AsyncCallback(OnConnectRequest), listener);                        //开始接受异步连接/** * BeginAccept 方法的第二个参数(object state)是一个用户定义的对象,它可以传递给回调函数,该参数可以用于在回调函数中传递额外的信息。* 比如我们将监听 Socket 对象作为 state 参数传递给了 BeginAccept 方法,在 BeginAccept 方法中,它会使用监听 Socket 对象去初始化一个 IAsyncResult 对象并返回。* IAsyncResult 对象包含了一个 AsyncState 属性,它的值就是传递给 BeginAccept 方法的第二个参数 state。这样,我们就能够在回调函数中使用该属性来获取监听 Socket 对象,以便继续监听客户端连接。* 当然,可以根据需要传递任何类型的对象作为 state 参数。这个参数对于在回调函数中传递额外的信息非常有用。*/}catch (Exception ex){MessageBox.Show(ex.Message);}}private void Print(string msg){//获取句柄再向下继续执行,以确保 Invoke() 方法执行不会出现异常。//IntPtr handlePtr = this.Handle;//出现异常/*** 通过 Invoke() 方法执行特定委托以避免“线程间操作无效”,请参考:<https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.forms.control.invoke?view=windowsdesktop-8.0>* 有关 Action() 强类型委托的相关内容,请参考:<https://learn.microsoft.com/zh-cn/dotnet/csharp/delegates-strongly-typed>,* 有关 Lambda 表达式语法,请参考:<https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/lambda-expressions>*/
#if falsethis.Invoke(new Action(() =>{richTextBox_Receive.AppendText($"[{DateTime.Now}] {msg}\n");  //在日志窗口显示消息}));
#elif falseAction action = () =>{richTextBox_Receive.AppendText($"[{DateTime.Now}] {msg}\n");  //在日志窗口显示消息};Invoke(action); 
#elseif (richTextBox_Receive.InvokeRequired){this.Invoke(new Action(() =>{richTextBox_Receive.AppendText($"[{DateTime.Now}] {msg}\n");  //在日志窗口显示消息}));}else{richTextBox_Receive.AppendText($"[{DateTime.Now}] {msg}\n");  //在日志窗口显示消息}
#endif}

3、方法3,使用BackgroundWorker和Invoke

BackgroundWorker backgroundWorkerText = new BackgroundWorker();
backgroundWorkerText.RunWorkerCompleted += backgroundWorkerText_RunWorkerCompleted;backgroundWorkerText.RunWorkerAsync();private void backgroundWorkerText_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e){if (textBox1.InvokeRequired){this.Invoke(new Action(() =>{textBox1.Text = "haha";}));}else{textBox1.Text = "haha";}
}

参考

  • 通过 Invoke() 方法执行特定委托以避免“线程间操作无效”,请参考:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.forms.control.invoke?view=windowsdesktop-8.0
  • 有关 Action() 强类型委托的相关内容,请参考:https://learn.microsoft.com/zh-cn/dotnet/csharp/delegates-strongly-typed,
  • 有关 Lambda 表达式语法,请参考:https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/lambda-expressions
  • 参考1
  • 参考2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/690963.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习---规则学习(一阶规则学习、归纳逻辑程序设计)

1. 一阶规则学习 “一阶”的目的&#xff1a;描述一类物体的性质、相互关系&#xff0c;比如利用一阶关系来挑“ 更好的”瓜&#xff0c;但实际应用 中很难量化颜色、 …、敲声的属性值。一般情况下可以省略全称量词。 命题逻辑&#xff1a;属性-值数据 色泽程度&#xff1a…

CSS:BFC

BFC&#xff0c;Block Formatting Context&#xff0c;块级格式化上下文&#xff0c;是一个独立的渲染区域或隔离的独立容器&#xff0c;它决定了其子元素如何布局&#xff0c;并且与这个区域外部的元素无关。 形成 BFC 的条件 float 的值不为 none&#xff08;left、right&a…

「连载」边缘计算(十六)02-19:边缘部分源码(源码分析篇)

&#xff08;接上篇&#xff09; edgecontroller剖析 edgecontroller功能模块启动函数的具体内容如下所示。 KubeEdge/cloud/pkg/edgecontroller/controller.go // Start controller func (ctl *Controller) Start(c *beehiveContext.Context) { var ctx context.Context c…

【Go语言最佳实践】错误只处理一次

我想提一下你应该只处理错误一次。 处理错误意味着检查错误值并做出单一决定。 // WriteAll writes the contents of buf to the supplied writer. func WriteAll(w io.Writer, buf []byte) {w.Write(buf) }如果你做出的决定少于一个&#xff0c;则忽略该错误。 正如我们在这里…

爬虫入门一

文章目录 一、什么是爬虫&#xff1f;二、爬虫基本流程三、requests模块介绍四、requests模块发送Get请求五、Get请求携带参数六、携带请求头七、发送post请求八、携带cookie方式一&#xff1a;放在请求头中方式二&#xff1a;放在cookie参数中 九、post请求携带参数十、模拟登…

HTTPS网络通信协议基础

目录 前言&#xff1a; 1.HTTPS协议理论 1.1协议概念 1.2加密 2.两类加密 2.1对称加密 2.2非对称加密 3.引入“证书” 3.1证书概念 3.2数据证书内容 3.3数据签名 4.总结 前言&#xff1a; 了解完HTTP协议后&#xff0c;HTTPS协议是HTTP协议的升级加强版&#xff0c…

基于Java的大学社团管理平台

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Springboot框架进行开发&#xff0c;前端采用主流的Vue.js进行开发。 整个平台包括前台和后台两个部分。 前台功能包括&#xff1a;首页、社团详情、申请加入、用户中心模块。后台功能包括&#xff1a;社团管理、分类管理…

Webpack和Rollup区别、使用场景、如何选择

Webpack 和 Rollup 都是前端构建工具&#xff0c;但它们的设计理念、侧重点和适用场景有所不同&#xff1a; Webpack 设计理念与功能&#xff1a; Webpack 是一个全能型的模块打包工具&#xff0c;不仅支持 JavaScript 模块的打包&#xff0c;还能处理 CSS、HTML、图片等各种静…

设计模式二:代理模式

1、什么是动态代理 可能很多小伙伴首次接触动态代理这个名词的时候&#xff0c;或者是在面试过程中被问到动态代理的时候&#xff0c;不能很好的描述出来&#xff0c;动态代理到底是个什么高大上的技术。不方&#xff0c;其实动态代理的使用非常广泛&#xff0c;例如我们平常使…

unity 使用VS Code 开发,VS Code配置注意事项

vscode 对应的插件&#xff08;unity开发&#xff09; 插件&#xff1a;.Net Install Tool,c#,c# Dev Kit,IntelliCode For C# Dev Kit,Unity,Unity Code Snippets 本人现在是用了这些插件 unity需要安装Visual Studio Editor 1、.Net Install Tool 设置 需要在设置里面配置…

人机、态势与感知之间的双向阈值开关及其交变特性

人-机双向阈值开关是一种可以根据阈值条件控制人和机器之间交互的装置或系统。它可以根据事先设定的条件来切换人和机器之间的工作模式。在这个开关中&#xff0c;有两个阈值&#xff0c;一个是人的阈值&#xff0c;另一个是机器的阈值。当人的阈值被触发时&#xff0c;系统将进…

jvm gc日志拿取与分析思路

前言 参考文章:Java中9种常见的CMS GC问题分析与解决 - 美团技术团队 排查过程 进入容器里 生产应用是跑在docker上的&#xff0c;所以需要先进入到应用里面去&#xff0c;步骤如下 1. docker ps 找到对应的应用id&#xff0c;比如 zxc 2. 进入容器内部 docker exec -it 7690…

Elasticsearch:什么是搜索引擎?

搜索引擎定义 搜索引擎是一种软件程序或系统&#xff0c;旨在帮助用户查找存储在互联网或特定数据库中的信息。 搜索引擎的工作原理是对各种来源的内容进行索引和编目&#xff0c;然后根据用户的搜索查询向用户提供相关结果列表。 搜索引擎对于希望快速有效地查找特定信息的用…

怎么清理mac系统缓存系统垃圾文件 ?怎么清理mac系统DNS缓存

很多使用苹果电脑的用户都喜欢在同时运行多个软件&#xff0c;不过这样会导致在运行一些大型软件的时候出现不必要的卡顿现象&#xff0c;这时候我们就可以去清理下内存&#xff0c;不过很多人可能并不知道正确的清内存方式&#xff0c;下面就和小编一起来看看吧。 mac系统是一…

读十堂极简人工智能课笔记07_模拟与情感

1. 数码式考察 1.1. 制作计算机动画或游戏 1.1.1. 想怎么制作都可以 1.2. 计算机模拟 1.2.1. 目标是建造一个虚拟的实验室&#xff0c;其行为与现实完全一致&#xff0c;只是某些变量由我们来控制 1.3. 对现实世界进行建模并不容易&#xff0c;需要非常谨慎地收集和使用数…

Vscode vim 插件使用Ctrl+C和V进行复制粘贴到剪切板

Vscode vim 插件使用CtrlC和V进行复制粘贴到剪切板 使用这一个插件的时候复制粘贴和其他软件互动的时候体验不好, 并且不可以用Ctrl c, Ctrl v很不爽 "vim.commandLineModeKeyBindings": [{"before" : ["Ctrl", "c"],"after&q…

httpd apache

虚拟主机 配置环境 [rootlocalhost ~]#cd /var/www/html/ [rootlocalhost html]#mkdir 123 [rootlocalhost html]#mkdir abc [rootlocalhost html]#ls 123 abc [rootlocalhost html]#cd 123/ [rootlocalhost 123]#echo 123 > index.html [rootlocalhost 123]#cd ../abc/ […

区块链/加密币/敏感/特殊题材专供外媒发稿,英文多国语言海外新闻营销推广

【本篇由言同数字科技有限公司原创】敏感题材是海外媒体在报道过程中常遇到的难题&#xff0c;需要平衡新闻真实性、公正性与敏感性。本文将探讨海外媒体报道敏感题材所面临的挑战&#xff0c;并介绍如何抓住机遇提高报道质量。 第一部分&#xff1a;敏感题材报道的挑战 报道…

【Python】图像裁剪与匹配

图像裁剪与匹配 在计算机视觉领域&#xff0c;图像处理是一项关键的任务&#xff0c;其中图像裁剪和匹配是常见的操作之一。本文将介绍如何使用OpenCV库进行图像裁剪与匹配&#xff0c;并展示一个简单的示例代码。 1. 引言 在图像处理中&#xff0c;有时需要从一张大图中截取…

泰山派摄像头使用-opencv流程

1. 泰山派添加camera 连接摄像头连接到usb接口,查看dev设备: # 在终端中输入如下命令&#xff0c;可以查看到camera设备资源&#xff1a; ls /dev/video* 检查板卡上的camera设备资源示例 也可以使用v4l2命令查看 v4l2-ctl --list-devices v4l2-ctl --list-devices是一个命令…