引言
在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验。所以在大量数据操作的应用上,需要使用多线程来处理这种情况。在c#中使用多线程很方便只需要使用System.Threading.Thread的一个实例的Start方法就行了,但是如何实现多线程之间的交互就不是那么简单。本文实现了用子线程去处理数据,并实时更新主线程的ui状态了。下面就开始一步步的去实现异步线程更新ui的demo程序吧。
应用背景
写入一定量的数据到文本文件中,同时需要在主界面中反应出写入数据的实时进度情况。要求:需要将写入数据封装成一个类。
实现过程
1、首先建立一个winform项目,在主窗体上拖入一个button,一个progressbar,一个lable。如下图所示。
2、编写一个处理数据的类(WriteDate),源代码如下。
public class DataWrite { public delegate void UpdateUI(int step);//声明一个更新主线程的委托 public UpdateUI UpdateUIDelegate; public delegate void AccomplishTask();//声明一个在完成任务时通知主线程的委托 public AccomplishTask TaskCallBack; public void 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、主界面中的代码如下:
首先要建立一个委托来实现非创建控件的线程更新控件。
delegate void AsynUpdateUI(int step);
然后编写多线程去启动写入数据的方法以及回调的函数。
private void btnWrite_Click(object sender, EventArgs e) { int taskCount = 10000; //任务量为10000 this.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); } //更新UI private void 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(); } } //完成任务时需要调用 private void Accomplish() { //还可以进行其他的一些完任务完成之后的逻辑处理 MessageBox.Show("任务完成"); }
效果如下:
总结
实现异步更新ui有很多种方法,但是我认为这种方式是比较灵活,能实时的获取到任务进行的状态,并且对之进行相应的处理。这种模式还适用于使用多个线程同时写入不同的数据到不同的文件中去。
源代码下载地址:Winform_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
我想从一个长期运行的方法状态更新。通常我会使用dispatcher回发到UI线程,但我对使用async Await很好奇。 为了简单起见: 但这是Fugly。此外,如果您去掉async和await关键字并将其替换为task.waitall,它仍将按预期执行。 注意:如果您想知道为什么我使用thread.sleep而不是task.delay,我实际上也在Silverlight中测试了这一点,异步等待
C# Winform编程 连接sqlite3 进行批量更新 想把方法抽出进行解耦 但有对进度条的控制内容 如何让进度中每一个更新,能够转递给外部的控件 progressBar1
本文向大家介绍总结Java中线程的状态及多线程的实现方式,包括了总结Java中线程的状态及多线程的实现方式的使用技巧和注意事项,需要的朋友参考一下 线程的状态 线程状态图: 说明: 线程共包括以下5种状态。 1. 新建状态(New) : 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。 2. 就绪状态(Runnable): 也被称为“可执行状态”
本文向大家介绍c# Winform 程序自动更新实现方法,包括了c# Winform 程序自动更新实现方法的使用技巧和注意事项,需要的朋友参考一下 Winform程序自动更新我也是第一次做,网上找了自动更新的源码,后来又根据在网上看到的一些方法,自己试了很久,最终还是有写错误,所以花了钱让别人帮忙调试成功的,下面是我自己捣腾出来的,方便大家借鉴,如果有什么错误的地方欢迎指正. 1、由于我是通过服务
我一直在四处寻找有类似问题的人,但没有找到任何东西。我正在编写一个使用WPF UI的C#应用程序。 为了更新progressbar,我不能像以前一样(在CLI中)使用多线程,因为它告诉我,如果UI元素不来自主线程,我就不能更新它。 一个解决方案是创建后台工作者。我已经实现了这个解决方案,它工作得很好,但是我希望将任务分配给更多的工作者/线程(多线程),以提高效率。 我不知道我该走的方向。如果有人能
本文向大家介绍WinForm实现跨进程通信的方法,包括了WinForm实现跨进程通信的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例展示了WinForm实现跨进程通信的方法,分享给大家供大家参考之用。具体方法如下: 主要功能代码如下: 希望本文所述实例对大家C#程序设计有所帮助。
本文向大家介绍Android 中通过实现线程更新Progressdialog (对话进度条),包括了Android 中通过实现线程更新Progressdialog (对话进度条)的使用技巧和注意事项,需要的朋友参考一下 作为开发者我们需要经常站在用户角度考虑问题,比如在应用商城下载软件时,当用户点击下载按钮,则会有下载进度提示页面出现,现在我们通过线程休眠的方式模拟下载进度更新的演示,如图(这里为
问题内容: 我刚刚开始进行android开发,并且更新UI确实使我很烦:/ 到目前为止,这是我一直在努力的工作- 它工作正常,但是每个人都说要在主线程中做图形,所以我正在尝试(但失败)将其传递给另一个线程。麻烦的是,我真的不知道怎么做,因为我从未真正使用过线程。 Google给出的有关使用Threads的示例似乎并不十分清楚,我也无法真正按照自己的意愿去做。我可以请某人在这里给我一个最基本的例子,