C#--耗时操作实现UI界面实时更新不阻塞(耗时操作解决窗体卡顿)

这篇具有很好参考价值的文章主要介绍了C#--耗时操作实现UI界面实时更新不阻塞(耗时操作解决窗体卡顿)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

C#实现窗体加载进度条或者百分比实时显示耗时操作的进度,方法有很多。但是经过我的学习、查找与实际应用,发现Task配合MethodInvoker最为高效便捷。下面我就来结合代码讲一下要注意的问题。

begininvoke界面刷新,C#(.NET)总结,C#,.net,多线程,Task,阻塞,Powered by 金山文档

基础知识

C#在winform上进行耗时操作往往会放置progressbar,问题是在UI线程上进行耗时操作就会导致UI线程阻塞,界面就会卡顿。所以势必要另开一个线程进行耗时操作,之后将耗时操作的过程实时反馈给UI线程即可,可问题是新开的线程向UI线程传递数据的时候,就会出现经典报错:

InvalidOperationException,并提示消息:“从不是创建控件的线程访问它。

这是因为NET原则上禁止跨线程访问。因为这样可能造成错误的发生,有一种简单粗暴的方法是禁止编译器对跨线程访问作检查,Control.CheckForIllegalCrossThreadCalls = false;可以实现访问,但是什么时候出错不敢保证。

Task

Task是一个升级版本的Thread的类,它非常的灵活,支持取消、阻塞等待、合并、多个Task协同操作......。总之使用Task编码高效易懂,你基本不用去研究Thread与ThreadPool了,虽然本质上还是这个。我个人理解Task就是对Thread的再次封装。

task

MethodInvoker

MethodInvoker 是位于System.Windows.Forms下的元数据,表示一个委托,该委托可以执行托管代码中声明为void且不接受任何参数的任何方法。在对控件的 invoke 方法进行调用时或需要一个简单委托又不想自己定义时可以使用该委托。 我是这样理解的,在新线程中使用MethodInvoker 委托执行耗时操作, 其实相当于是在主线程中执行的, 这样就避免了 跨线程访问控件

methodinvoker

示例代码

begininvoke界面刷新,C#(.NET)总结,C#,.net,多线程,Task,阻塞,Powered by 金山文档
 private void button1_Click(object sender, EventArgs e)
        {
            progressBar1.Visible = true;
            Task task = new Task(() =>
            {
                int i = 0;
                while (++i < 100)
                {
                    Thread.Sleep(10);//模拟耗时操作
                    MethodInvoker mi = new MethodInvoker(() =>
                    {
                        progressBar1.Value = i;
                        this.label1.Text = i.ToString();
                    });
                    this.BeginInvoke(mi);
                }
            });
            task.Start();
            task.ContinueWith(t => {
                progressBar1.Visible = false;
            },TaskScheduler.FromCurrentSynchronizationContext());
            
        }

线程的延续采用ContinueWith解决

BeginInvoke解决界面的刷新问题

TaskScheduler.FromCurrentSynchronizationContext() 解决跨线程访问报错

 private void button2_Click(object sender, EventArgs e)
        {
            Task task1 = new Task(() =>
            {
                M1();
                MethodInvoker mi = new MethodInvoker(() =>
                {
                   
                    this.label1.Text = "1";
                });
                this.BeginInvoke(mi);

                M2();
                mi = new MethodInvoker(() =>
                {
                   
                    this.label1.Text = "2";
                });
                this.BeginInvoke(mi);
            });
            task1.Start();
          
            this.label1.Text="主线程开始运行!" ;
        }

        private void M1()
        {
            Thread.Sleep(2000);
        }
        private void M2()
        {
            Thread.Sleep(1000);
        }

button2的方式可以在task线程中按顺序执行耗时操作。文章来源地址https://www.toymoban.com/news/detail-778724.html

到了这里,关于C#--耗时操作实现UI界面实时更新不阻塞(耗时操作解决窗体卡顿)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WebSocket实现后端数据变化,通知前端实时更新数据

    背景 ​ 项目中需要做一个消息提示功能,当有用户处理相关待办信息后,别的用户需要实时更新处理后的待办信息。 解决方案: ​ 1、使用最原始的方法,写个定时器去查询待办信息。但这种方式在大多数情况是不被允许的,它会浪费系统中的许多资源,同时也并不是完全

    2024年04月15日
    浏览(49)
  • uniapp:实现手机端APP登录强制更新,从本地服务器下载新的apk更新,并使用WebSocket,实时强制在线用户更新

    实现登录即更新,或实时监听更新 本文介绍的是在 App打开启动 的时候调用更新,点击下方链接,查看使用 WebSocket 实现 实时 通知 在线用户 更新。 uniapp:全局消息是推送,实现app在线更新,WebSocket,apk上传: 背景 :内部手持机app开发功能,需要更新的到车间各个手持机上。

    2024年02月03日
    浏览(40)
  • Android:实时更新时间

    心想着也就是更新精确到分钟,不用精确到秒,定时器就没有必要,系统是有广播 Intent.ACTION_TIME_TICK 可以直接用 动态注册广播 主方法里面调用一下 接收广播并处理 精确到时:分的方法 

    2024年02月15日
    浏览(108)
  • 前端大屏数据实时更新

    在页面中使用  setInterval  每隔几秒去获取一下数据。伪代码如下: 一般不建议这样使用,因为会给页面造成性能问题。 使用  websocket 如果使用 websocket 纯前端无法独立完成,需要 后台  配合提供相应的接口。 使用 SSE(Server-Sent Events) , 纯前端无法独立完成,需要 后台  配

    2024年02月05日
    浏览(62)
  • WebSocket 网络协议(实时更新 )

    WebSocket 是一种在客户端和服务器之间建立双向通信信道的网络协议。它在客户端和服务器之间建立一个持久的、全双工的连接,允许数据在两个方向上实时传输,而不需要像HTTP一样进行多次请求和响应。  WebSocket 的主要优势是减少了服务器和客户端之间的通信延迟,因为数

    2024年01月17日
    浏览(50)
  • Python如何随数据更新实时画图?Python实时动态绘图

    在数据分析和可视化场景中,我们常常需要实现实时动态图表,比如每分钟读取数据库新的记录,及时更新图表显示最新数据,而不是静态显示某个时间点的数据。本文将介绍使用Python matploblib库的animation功能实现实时动态绘图的方法。 问题背景 我们有一个Excel表,其中记录

    2024年02月12日
    浏览(51)
  • ClickHouse如何处理实时更新

    本文通过示例介绍如何处理ClickHouse实时更新。OLAP数据库并不欢迎数据变更操作,ClickHouse也不例外,和其他OLAP产品一样,刚开始ClickHouse甚至不支持更新,更新能力是后来才加上的,但是按照ClickHouse方式增加的。当前ClickHouse更新是异步的,使得在交互应用中难以使用。有很多

    2024年02月15日
    浏览(47)
  • CTF常用工具_实时更新

    近期在做一些ctf题,其中会涉及到许多工具,起初我会使用百度网盘在每一篇博客放置对应的工具,但因网盘上传有上限,所以现在我将练习中所用到所有的工具放置在这篇文章中。 需要下载的小伙伴可随时拿取,分享有效期为永久分享。 常用工具及常用网站为实时分享!

    2024年02月04日
    浏览(46)
  • Java面试基础|数据结构 -实时更新

    1.HashMap和ConcurrentHashMap介绍 核心是一个Node数组, 数据结构与hashMap相似 使用CAS操作来实现无锁的更新,提高了并发性。当更新节点时,它会使用CAS来替换节点的值或链接,如果CAS失败,表明有其他线程也在进行修改,当前线程可以重试或锁定节点 对于复杂的结构修改操作

    2024年01月17日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包