引言

在进行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();
}
}

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实现多线程异步更新UI(进度及状态信息)

[转]Winform实现多线程异步更新UI(进度及状态信息)的更多相关文章

  1. Winform实现多线程异步更新UI(进度及状态信息)

    引言 在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验.所以在大量数 ...

  2. Winform之跨线程更新UI

    Winform之跨线程更新UI 使用`Invoke`或者`BeginInvoke`与UI线程交互示例 参考及源码 使用Invoke或者BeginInvoke与UI线程交互示例 private void ...

  3. 使用AsyncTask异步更新UI界面及原理分析

    概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...

  4. Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面

    Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...

  5. Android异步处理二:使用AsyncTask异步更新UI界面

    在<Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面>中,我们使用Thread+Handler的方式实现了异步更新UI界面,这一篇中,我们介绍一种更为简 ...

  6. Android异步更新UI的四种方式

    Android异步更新UI的四种方式 2015-09-06 09:23 segmentfault 字号:T | T 大家都知道由于性能要求,android要求只能在UI线程中更新UI,要想在其他线程中 ...

  7. Android 通过广播来异步更新UI

    之前的项目里要做一个异步更新UI的功能,可是结果出现了ANR,所以想写个demo来測试究竟是哪个地方出现了问题,结果发现原来的思路是没有问题,郁闷~~ 如今这个demo 就是模拟项目里面 的步骤 1. ...

  8. Flutter学习笔记(31)--异步更新UI

    如需转载,请注明出处:Flutter学习笔记(31)--异步更新UI 大家都知道,子线程不能操作UI控件,在我们Android的日常开发中,经常会遇到网络请求数据通过线程间通信,将数据发送到UI线程中 ...

  9. 关于Winform 2.0以后多线程不能更新UI的办法

    DotNet 2.0以后Winform在多线程Debug模式下更新UI会报这个错: 线程间操作无效: 从不是创建控件"XXX"的线程访问它. 解决办法如下: 1.在Winform的 ...

  10. winform中如何在多线程中更新UI控件--ListView实时显示执行信息

    1.在winform中,所有对UI的操作,都得回到UI线程(主线程)上来,才不会报错 线程间操作无效: 从不是创建控件的线程访问它. 2.在winform中,允许通过Control.invoke对控件 ...

随机推荐

  1. python多线程完成模拟支付请求

    import asyncioimport sysfrom queue import Queuesys.path.append("../")from tool.__init__ im ...

  2. VS2019插件更新慢的解决办法

    VS2019更新巨慢,可以尝试通过以下几个方法解决: 1. 关闭IPV6 关闭IPV6:Win10怎么样禁用IPV6 如何关闭IPV6协议-百度经验 (baidu.com) 2. 选择最快的DNS 百 ...

  3. CMDB实践指南:项目规划与实施策略解析

    随着现代企业IT系统的日益复杂,如何有效管理这些庞大的IT资产和资源,成为每个企业必须面对的重要问题.CMDB应运而生,帮助企业集中管理IT资源,维护系统的稳定性,并支持故障排查与决策制定.本文将深入 ...

  4. 学习JavaScript第四天

    文章目录 1 回顾 内置对象 2 内置对象 2.1 Function 2.2 Global 3 DOM 部分知识点介绍 4 BOM 4.1 window ① 弹框 ② 打开关闭窗口 ③ 页面滚动 ④ ...

  5. AI年代,谁还用难用的Keil?快快换CLion!!! 破解+环境替换 [上]

    安装Clion 由于这个地方碰壁比较多,所以大家严格按照我下面的安装节奏就可以了! 记得CLion的版本等,和我所说的不匹配也会导致破解失败. 包能破解安装上的. 1.下载 链接:https://pa ...

  6. 重温c语言之,7天开整,就是随便的写写,第二天

    一:操作符 除法: 如果都是整数,除数,被除数都是整数,那么结果:就是整数的商(没有小数部分的),例如:7/2=3: 如果除数或者被除数其中一个是浮点数,那么结果就是(条件是:能除尽的,并且小数在基础 ...

  7. 国内计算机领域相关的SCI和EI期刊,以及好中的SCI和EI期刊(不限国内外)

    好中的: SCI刊: EI刊: EI会议: 参考: CCF发布计算领域高质量科技期刊分级目录   国内的: SCI-Expanded   1. <Journal of Computer Scie ...

  8. K8S1.16.4+kubeflow1.0安装

    K8S1.16.4+kubeflow1.0安装文档 一.简介 本文档编写原因:之前kubeflow1.0安装手册出现较多不可控问题,计划重新安排一个能够完全离线安装的K8S和kubeflow环境. 备 ...

  9. 来了,超全MQTT实用示例

    Air201快速入门之MQTT示例 合宙Air201资产定位模组--是一个集成超低功耗4G通信.语音通话.超低功耗定位.计步.震动.Type-C.充电.放音.录音等功能的超小PCBA. 内部集成高效. ...

  10. 第三篇:低功耗模组Air724UG硬件设计手册

    ​ 今天我们分享最后一篇. 3.20 省电功能 根据系统需求,有两种方式可以使模块进入到低功耗的状态.对于AT版本使用"AT+CFUN"命令可以使模块 进入最少功能状态. 具体的功 ...