博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Winform实现多线程异步更新UI(进度及状态信息)
阅读量:6974 次
发布时间:2019-06-27

本文共 2711 字,大约阅读时间需要 9 分钟。

引言

在进行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
你可能感兴趣的文章
JS中的继承模式
查看>>
生命周期组件 Lifecycle 源码解析(一)
查看>>
TNW-获取微信公众号的 access_token
查看>>
广州,后会有期
查看>>
谈谈关于 iOS 的架构以及应用
查看>>
ElasticSearch 学习总结
查看>>
【Nodejs学习之旅·1-1】为何选择Nodejs
查看>>
Docker安装
查看>>
很简单的next.js数据获取规范
查看>>
String方法小总结
查看>>
Vue 使用篇(二):Vue父子组件间的数据传输
查看>>
区块链技术融合云计算是如何引领未来新趋势
查看>>
关于Flutter 您必须知道的知识点!!!
查看>>
微服务间的调用和应用内调用有啥区别
查看>>
iOS二进制和资源包的自检
查看>>
20-多态
查看>>
互联网寒冬里的菜鸟求职日记(水文)
查看>>
css中那些令人迷惑的东西
查看>>
从Context说到Binder
查看>>
阿里RocketMq试用记录+简单的Spring集成
查看>>