首页 > 其他分享 >Winform跨线程访问UI

Winform跨线程访问UI

时间:2023-08-10 22:44:06浏览次数:46  
标签:log Invoke richTextBox1 UI 线程 Winform AppendText

在开发winfrom应用时,经常遇到异常:System.InvalidOperationException:“线程间操作无效: 从不是创建控件“xxxx”的线程访问它。出现这个异常的原因是创建这个UI的线程,和当前访问这个UI的线程不会是同一个。Winform为了防止线程不安全,因此对这个跨线程访问抛出异常,禁止这个操作。

解决方案

使用InvokeRequired属性判断是否线程安全。

            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.Invoke(new Action(() =>
               {
                   richTextBox1.AppendText(log);
                   richTextBox1.AppendText("\r\n");
               }));
            }
            else
            {
                richTextBox1.AppendText(log);
                richTextBox1.AppendText("\r\n");
            }

如果richTextBox1是在非主线程创建或找不到其句柄,那么richTextBox1.InvokeRequired=false返回false,就会走else分支,如果在找不到句柄的情况下,else里的代码也会抛异常。为了更加安全,需要进一步对句柄进行判断,用IsHandleCreated判断是否创建了句柄。

            if (richTextBox1.InvokeRequired)
            {
                richTextBox1.Invoke(new Action(() =>
               {
                   richTextBox1.AppendText(log);
                   richTextBox1.AppendText("\r\n");
               }));
            }
            else
            {
                if (richTextBox1.IsHandleCreated)
                {
                    richTextBox1.AppendText(log);
                    richTextBox1.AppendText("\r\n");
                }

            }

上面代码基本上没什么问题了。但是稍显麻烦,可以进行精简一下。使用哦当前FormInvoke方法而不是具体某个ControlInvoke,这样能确保当前的操作一定在当前的UI线程中,且句柄一并被创建。

        private void Log(string log)
        {
            Invoke(new Action(() =>
            {
                richTextBox1.AppendText(log);
                richTextBox1.AppendText("\r\n");
            }));
        }

其实在winform中跨线程访问UI很常见,比如在一个子窗口中进行了某个操作,需要更新主窗口里的某些状态或数据,如果稍不注意就会出现跨线程访问UI的异常,因此Invoke方法应该被广泛使用。

标签:log,Invoke,richTextBox1,UI,线程,Winform,AppendText
From: https://www.cnblogs.com/ycit/p/17621798.html

相关文章

  • CompletableFuture异步多线程
    importjava.util.concurrent.CompletableFuture;importjava.util.concurrent.ExecutionException;publicstaticvoidmain(String[]args)throwsInterruptedException,ExecutionException{longstartTime=System.currentTimeMillis();//调用用户服......
  • 作为网络报表分析工具的Quick BI,其功能如何
    QuickBI是一款网络报表分析工具,它可以帮助用户快速、方便、灵活地对数据进行可视化分析和展示。本文将介绍QuickBI的主要功能和优势,以及一些应用场景和客户案例。QuickBI的主要功能有: 数据连接模块:支持多种云上数据源和自建数据库的接入,如RDS、ADS、MaxCompute、ECS自建MySQL、......
  • vue3+vite+view-ui-plus 实现按需引用
    现有项目使用的是vue3+vite+view-ui-plus由于公司要求秒开速度对h5页面进行优化,首先想到的是把组件的引用从全量引用打包改成按需引用;下面是改之前的 view-ui-plus引用配置,简单粗暴直接在main.ts中引用  importViewUIPlusfrom'view-ui-plus'import'view-ui-plus/d......
  • 进程 线程 协程的区别
    进程进程是操作系统,进行资源分配和调度的基本单位,多个进程之间相互独立,进程的特点是稳定性好,如果一个进程崩溃,不影响其他进程,但是进程消耗资源大,开启的进程数量有限制线程线程是cpu进行资源分配和调度的基本单位,线程是进程的一部分,是比进程更小的,能独立运......
  • java多线程:死锁
    一、死锁的定义   多线程以及多进程改善了系统资源的利用率并提高了系统的处理能力。然而,并发执行也带来了新的问题——死锁。所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。   所谓死锁是指两个或两个以上的线程在......
  • Hadoop集群启停命令以及Web UI界面的相关介绍
    1、Hadoop集群的启停命令(我是将文件都配置好了,直接使用最方便的启停命令就能进行使用)start-all.shstop-all.sh2、HDFS集群的WebUI界面主要是通过命令行:ifconfig获取到本虚拟机的ip地址,然后输入:ip:9870进行访问即可3、YARN集群的WebUI界面可以使用以下命令访问:ht......
  • VUE+ElementUI的表单验证二选一必填项,并且满足条件后清除表单验证提示
    上代码<el-form-itemlabel="出库单号"prop="ecode"ref="ecode":rules="rules.ecode"><el-inputv-model="queryParams.ecode"placeholder="出库单号和出库箱号至少填写一项"clearable......
  • layui - table 回填 - 相关
    table.render({elem:'#userTable',url:'../sysRole/getUserList',title:'用户列表',page:true//开启分页,cols:[[{type:'checkbox'},{......
  • .configure error SSL modules require the OpenSSL library.
    CentOS6.5下安装Tengine执行配置命令./configure时提示以下错误:./configure:error:SSLmodulesrequiretheOpenSSLlibrary.Youcaneitherdonotenablethemodules,orinstalltheOpenSSLlibraryintothesystem,orbuildtheOpenSSLlibrarystaticallyfromt......
  • 精简的Vue Elenent ui界面
    仓库地址:https://gitee.com/JSTGitee/element-jst-admin 登录  首页   表格   前言该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统开发。基于Vue2,使用vue-cli2脚手架,引用Elementui组件库,方便开发快速简洁好看的组件。 功能......