winform实现多线程异步更新ui(进度及状态信息)

防空洞123 防空洞123     2022-08-23     416

关键词:

引言

在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验。所以在大量数据操作的应用上,需要使用多线程来处理这种情况。在c#中使用多线程很方便只需要使用System.Threading.Thread的一个实例的Start方法就行了,但是如何实现多线程之间的交互就不是那么简单。本文实现了用子线程去处理数据,并实时更新主线程的ui状态了。下面就开始一步步的去实现异步线程更新ui的demo程序吧。

应用背景 


写入一定量的数据到文本文件中,同时需要在主界面中反应出写入数据的实时进度情况。要求:需要将写入数据封装成一个类。

实现过程


1、首先建立一个winform项目,在主窗体上拖入一个button,一个progressbar,一个lable。如下图所示。

 
2、编写一个处理数据的类(WriteDate),源代码如下。
publicclass DataWrite
    {
        publicdelegatevoid UpdateUI(int step);//声明一个更新主线程的委托public UpdateUI UpdateUIDelegate;

        publicdelegatevoid AccomplishTask();//声明一个在完成任务时通知主线程的委托public AccomplishTask TaskCallBack;
       
        publicvoid Write(object lineCount)
        {
            StreamWriter writeIO = new StreamWriter("text.txt", false, Encoding.GetEncoding("gb2312"));
            string head = "编号,省,市";
            writeIO.Write(head);
            for (int i = 0; i < (int)lineCount; i++)
            {
                writeIO.WriteLine(i.ToString() + ",湖南,衡阳");
                //写入一条数据,调用更新主线程ui状态的委托
                UpdateUIDelegate(1);
            }
            //任务完成时通知主线程作出相应的处理            TaskCallBack();
            writeIO.Close();
        }
    }

 

3、主界面中的代码如下:
  首先要建立一个委托来实现非创建控件的线程更新控件。 
delegatevoid AsynUpdateUI(int step);

 

   然后编写多线程去启动写入数据的方法以及回调的函数。
privatevoid btnWrite_Click(object sender, EventArgs e)
        {
            int taskCount = 10000; //任务量为10000this.pgbWrite.Maximum = taskCount;
            this.pgbWrite.Value = 0;

            DataWrite dataWrite = new DataWrite();//实例化一个写入数据的类
            dataWrite.UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
            dataWrite.TaskCallBack += Accomplish;//绑定完成任务要调用的委托
            Thread thread = new Thread(new ParameterizedThreadStart(dataWrite.Write));
            thread.IsBackground = true;
            thread.Start(taskCount);
        }

        //更新UIprivatevoid UpdataUIStatus(int step)
        {
            if (InvokeRequired)
            {
                this.Invoke(new AsynUpdateUI(delegate(int s)
                {
                    this.pgbWrite.Value += s;
                    this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
                }), step);
            }
            else
            {
                this.pgbWrite.Value += step;
                this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
            }
        }

        //完成任务时需要调用privatevoid Accomplish()
        {
            //还可以进行其他的一些完任务完成之后的逻辑处理
            MessageBox.Show("任务完成");
        }
效果如下:
总结

实现异步更新ui有很多种方法,但是我认为这种方式是比较灵活,能实时的获取到任务进行的状态,并且对之进行相应的处理。这种模式还适用于使用多个线程同时写入不同的数据到不同的文件中去。
源代码下载地址:http://download.csdn.net/detail/mingge38/9378852

c#winform不是用this.dispatcher.invoke来异步更新ui吗?

c#winform不是用this.dispatcher.invoke来异步更新ui吗?参考技术A因为两个线程虽说是异步执行,在宏观看来是同时执行的,但是大多个人电脑只有一个cpu并不是多CPU,也就是说并不能真正实现多个线程同时执行;但为了达到类似的效果... 查看详情

如何在android开发中用asynctask异步更新ui界面

...建的Handler传递消息的方式,调用相关的回调函数,从而实现UI界面的更新。  2  AsyncTask抽象出后台线程运行的五个状态,分别是:1、准备运行,2、正在后台运行,3、进度更新,4、完成后台任务,5、取消任务,对于这五个... 查看详情

winform跨线程访问控件异常

WinForm跨线程访问控件异常最近做了个WinForm的小项目,遇到个简单的问题记录下。需求:点击”下载“,显示正在下载,下载完后更新状态为”ready“(要求用多线程,避免前台卡死)。做法新建一个线程,在新线程中下在更新... 查看详情

winform跨线程更新ui控件常用方法汇总(代码片段)

#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现“线程间操作无效:从不是创建控件的线程访问它”的异常。处理跨线程更新WinformUI控件常用的方法有4种:1.通过UI线程的SynchronizationContext的Post/Send方法... 查看详情

winform中如何在多线程中更新ui控件--listview实时显示执行信息

1、在winform中,所有对UI的操作,都得回到UI线程(主线程)上来,才不会报错   线程间操作无效:从不是创建控件的线程访问它。2、在winform中,允许通过Control.invoke对控件进行操作。如下代码:privatevoidbtnTest_Click(objectsend... 查看详情

c#winform多线程更新数据,ui卡顿现象。

我要通过串口采集数据,然后在软件上显示出来。使用线程来采集,想做成异步程序。不知道哪错了,有卡顿现象。主要代码如下://读取D寄存器信息privatevoidReadPLC_D_Date()inti=0;foreach(XinYangClass.PLCDateMainminPLC_D_List)stringDValue=ReadPLCDa... 查看详情

多线程任务更新 1 个进度条 - UI C# WPF

】多线程任务更新1个进度条-UIC#WPF【英文标题】:Multiplethreadstasksupdating1progressbar-UIC#WPF【发布时间】:2021-07-1619:30:51【问题描述】:我一直在四处寻找有类似问题的人,但没有找到任何东西。我正在使用WPFUI编写C#应用程序。要... 查看详情

异步多线程

UI只能在主线程中完成更新,在子线程中更新UI报错如下Onlytheoriginalthreadthatcreatedaviewhierarchycantouchitsviews.但是,在主线程中完成耗时操作容易引起使用体验不佳,进程卡顿问题,为了解决此问题引入异步多线程 异步多线程 查看详情

c#中我要实现大量的httpwebrequest,但是不想winform假死住,请问用多线程还是异步?

我是用了一个for循环,里面执行httpwebrequest但是一开始执行winforms就基本假死住了一般客户端设计要求来说,耗时处理放在线程中,比如网络请求,数据循环操作之类参考技术A当然是用异步了,asyn/wait 查看详情

asynctaskhandlerthreadintentservice和线程池

...果传递给主线程用于更新UI。可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.  AsyncTask并不合适进行特别耗时的后台任务,对于特别... 查看详情

flutter功能型组件:异步ui更新(futurebuilderstreambuilder)(代码片段)

...网数据接收流)的进度。当然,通过StatefulWidget完全可以实现上述这些功能。但由于在实际开发中依赖异步数据更新UI的这种场景非常常见,因此Flutter专门提供了FutureBuilder和StreamBuilder两个组件来快速实现这种功能。接口描述Futur... 查看详情

androidasynctask怎么用

...多时候,UI界面更新比较耗时,如果不使用异步加载方式实现的话,很容易导致ANR异常。出于安全考虑,一些耗时操作最好用异步方式实现。AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提... 查看详情

service服务

...例,用start()方法启动:newMyThread().start();    2、实现Runnable接口:newThread(newRunnable()){实现run()}  子线程中更新UI:    子线程中不允许更新UI,如果想在子线程中更新UI需要用到异步消息处理机制。异步消息 查看详情

c#winform实现windows文件文件夹搜索功能

要求:1、必须显示当前正在搜索的文件名或文件夹名;2、必须实时更新搜索的结果;3、实现多选择路径的搜索,即可以复选路径(可选);4、实现精确的进度条功能(可选);5、不允许使用第三方控件,否则不给分;6、以上... 查看详情

c#winform线程中更新ui

幸好今天是周末,有时间把这个问题记录一下.在多种语言之间切换,发现开发效率降的很低了,开发成本都集中到调式上了,C/C++这些放弃很久了,突然感觉线程这个问题搞的有点烦躁我这里提到的线程中更新UI,在大数据大并发... 查看详情

异步线程之asynctask

...应。2、解决新线程不能更新UI组件的问题2.1、使用Handler实现线程通信2.2、Activity.runOnUiThread(Runnable)2.3、View.post(Runnable)2.4、View.postDel 查看详情

多线程环境的ui控件属性更新

Winform:publicdelegatevoidUpadataTextCallBack(stringstr,TextBoxtext);publicvoidUpadtaText(stringstr,TextBoxtext){  if(text.InvokeRequired)  {    UpadataTextCallBackupadataTextCallBack=UpadtaText;    t 查看详情

优雅设计封装基于okhttp3的网络框架:多线程下载添加数据库支持(greendao)及进度更新(代码片段)

通过前三篇博文的学习,已经编码实现多线程下载功能的核心代码,通过多个线程之间的管理和调度来处理下载任务,最后再引入队列机制来完善功能。此篇博文主旨需要将下载的进度存储到数据库中,目的是为... 查看详情