当前位置: 首页 > news >正文

C#【必备技能篇】Winform跨线程更新进度条的实例

文章目录

  • 实例一:【方便理解,常用!】
    • 源码:
    • 运行效果:
  • 实例二:【重在理解代码本身】
    • 源码:
    • 运行效果:
  • 参考:

实例一:【方便理解,常用!】

跨线程更新进度条【事件触发(进度条值增加的方法在另一个命名空间下的类中)】

源码:

AddNum.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ProgressBarAddNum
{public class AddNum{public static int Num = 0;public delegate void UpdateProgress(int index);public static event UpdateProgress onUpdateProgress;public static void Add(){UpdateProgressMethod(Num > 100 ? 0 : Num);Num+=2;          }public static void UpdateProgressMethod(int i){if (onUpdateProgress != null){onUpdateProgress.BeginInvoke(i, null, null);}}}
}

Form1.cs
在这里插入图片描述

using ProgressBarAddNum;
using System;
using System.Threading;
using System.Windows.Forms;namespace WindowsFormsApp1
{public partial class Form1 : Form{public Form1(){InitializeComponent();AddNum.onUpdateProgress += AddNum_onUpdateProgress;//注意:此事件绑定只绑定一次,不能多次绑定}public static Thread thread;private void button1_Click(object sender, EventArgs e){AddNum.Num = 0;thread = new Thread(Process);thread.IsBackground = true;thread.Start();}public delegate void UpdateProgress(int index);private void AddNum_onUpdateProgress(int index){if (progressBar1.InvokeRequired){UpdateProgress dus = new UpdateProgress(AddNum_onUpdateProgress);this.BeginInvoke(dus, new object[] { index });//方法一//this.BeginInvoke(dus, index);//方法二//progressBar1.Invoke(dus, new object[] { index });//方法三:也可以同时更新textBox1的值【???】//progressBar1.Invoke(dus, index);//方法四:也可以同时更新textBox1的值【???】}else{progressBar1.Value = index;textBox1.Text = index.ToString();//注意:同时更新textBox1的值}}private void Process(){while (true){if (AddNum.Num <= 100){AddNum.Add();Thread.Sleep(50);}else{break;}}}private void button2_Click(object sender, EventArgs e){if (thread != null){thread.Abort();thread = null;}progressBar1.Value = 0;textBox1.Text = "0";}}
}

运行效果:

在这里插入图片描述

实例二:【重在理解代码本身】

C#中的事件是建立在委托的基础上,标准的事件模型应该包括以下几点:

  • 声明一个用于定义事件的委托,这里用系统自带的泛型委托原型EventHandler,如:public delegate void EventHandler(object sender,TEventArgs e);这里面的TEventArgs是由我们自定义的参数类型,继承自EventArgs基类
  • 事件参数的名称以EventArgs结束
  • 声明事件的委托原型即EventHandler,它的返回值为void
  • 声明事件的委托原型即EventHandler,它有两个参数:sender和e,sender表示事件触发者,e表示事件触发时的参数
  • 事件的声明是在普通委托声明的前面加上,event关键字,如:public event EventHandler FileUploaded;

源码:

文件下载时,要实时更新进度条,这时更新进度的方法就应该由下载类在下载的同时根据实时的下载进度利用事件去同步更新进度条的值。代码如下:
在这里插入图片描述

using System;
using System.Threading;
using System.Windows.Forms;namespace WindowsFormsApp2
{public partial class Form1 : Form{public Form1(){InitializeComponent();}private void ShowProcess(object sender, FileUploaderEventArgs e){//定义委托Action t = () =>{progressBar1.Value = e.FileProgress;label1.Text = e.FileProgress.ToString();};//跨线程操作this.BeginInvoke(t);Thread.Sleep(100);//【注意】:触发事件后的方法要执行完毕,才会退出while中的触发事件代码}private void button1_Click_1(object sender, EventArgs e){FileUploader f1 = new FileUploader();f1.FileUploaded += ShowProcess;                  //绑定事件ThreadPool.QueueUserWorkItem((a) => f1.Upload());//加入线程池}}/// <summary>/// 文件下载类/// </summary>class FileUploader{public event EventHandler<FileUploaderEventArgs> FileUploaded;//定义事件public void Upload(){var e = new FileUploaderEventArgs() { FileProgress = 0 };while (e.FileProgress < 100){//DoSomething();//执行一些下载任务e.FileProgress++;FileUploaded(this, e);//触发事件//Thread.Sleep(100);//【注意】:或者注释掉上边的代码,使用这个,实际中更常用}}}/// <summary>/// 自定义参数/// </summary>class FileUploaderEventArgs : EventArgs{public int FileProgress { get; set; }}
}

运行效果:

在这里插入图片描述

参考:

https://www.cnblogs.com/maitian-lf/p/3654146.html

http://www.lryc.cn/news/624.html

相关文章:

  • (1分钟速通面试) 矩阵分解相关内容
  • this指向
  • 安卓小游戏:小板弹球
  • 7、单行函数
  • 华为机试题:HJ56 完全数计算(python)
  • opencv——傅里叶变换、低通与高通滤波及直方图等操作
  • 【NGINX入门指北】 进阶篇
  • Python中关于@修饰符、yeild关键词、next()函数的基本功能简述
  • 结合Coverity扫描Spring Boot项目进行Path Manipulation漏洞修复
  • 【FFMPEG源码分析】从ffplay源码摸清ffmpeg框架(一)
  • C++蓝桥杯 基础练习,高精度加法,输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。
  • MySQL面试题:SQL语句的基本语法
  • Fluid-数据编排能力原理解析
  • 并发线程、锁、ThreadLocal
  • CMMI-结项管理
  • 网络通信协议是什么?
  • 阶段5:Java分布式与微服务实战
  • 我的创作纪念日
  • Qml学习——动态加载控件
  • 设计模式之职责链模式
  • MySQL入门篇-MySQL 8.0 延迟复制
  • FPGA时序约束与分析 --- 实例教程(1)
  • go深拷贝和浅拷贝
  • linux网络系统层面的配置、管理及操作命令汇总
  • R数据分析:孟德尔随机化中介的原理和实操
  • 【C++】 类和对象 (下)
  • asp获取毫秒时间戳的方法 asp获取13位时间戳的方案
  • Python基础篇(十五)-- Python程序接入MySQL数据库
  • 程序员不得不知道的 API 接口常识
  • 【项目精选】基于Java的银行排号系统的设计与实现