0
由于程序计算耗时较长,需要在耗时的地方加入循环滚动的进度条,经过学习和测试,分享一种Winform加载进度条的方法,经过验证可以达到既定需要,暂时没遇到明显报错,这里将实现过程与代码进行分享。
- 创建winform应用程序,加载一个buttom和一个ProgressBar控件,用于触发和显示进度条。
2.写两个方法,一个模拟耗时的程序,可以替换为自己的程序,一个用于循环更新进度条ProgressBar的值,这两个方法后面会被两个线程执行。
// 耗时程序,可以替换为自己的程序 public void test1() { DateTime dt1 = DateTime.Now; double step; while (true) { DateTime dt2 = DateTime.Now; step = dt2.Subtract(dt1).TotalSeconds; if (step > 12 ) { break; } } } /// 进度条循环方法 private void startProgress() { // 显示进度条控件. progressBar1.Visible = true; // 设置进度条最小值. progressBar1.Minimum = 1; // 设置进度条最大值. progressBar1.Maximum = 15; // 设置进度条初始值 progressBar1.Value = 1; // 设置每次增加的步长 progressBar1.Step = 1; // 循环执行 int x = 0; while (x <= 15) { if (stop == true) { progressBar1.Value = 15; thread2.Abort(); break; } // 每次循环让程序休眠300毫秒 System.Threading.Thread.Sleep(300); // 执行PerformStep()函数 progressBar1.PerformStep(); if (x == 15) { x = 0; progressBar1.Value = 1; progressBar1.Step = 1; } x++; } }
- 在buttom点击事件下写主要的控制逻辑,思路是点击按钮后,两个线程同时启动,在test1()执行结束之前,进度条一直循环滚动;test1()执行结束后,两个线程都结束。
代码分享
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ProgressBar { public partial class Form1 : Form { bool stop; Thread thread2; public Form1() { InitializeComponent(); System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; } private void button1_Click(object sender, EventArgs e) { // 初始化progressBar1及控制参数 stop = false; progressBar1.Value = 1; progressBar1.Visible = false; // 进度条刚开始不显示 bool thr1end = false; bool thr1over = false; Thread thread1 = new Thread(new ThreadStart(test1)); // test1()计算用的主调方法,往往比较耗时 thread1.Priority = ThreadPriority.Highest; thread1.Start(); thread2 = new Thread(new ThreadStart(startProgress)); // 更新进度条的值 thread2.Start(); // 判断当计算线程执行结束时,控制进度条线程也马上结束 while (!thr1over) { thr1end = thread1.IsAlive; System.Windows.Forms.Application.DoEvents(); if (!thr1end || thr1over) { thread1.Interrupt(); thread1.Abort(); stop = true; thr1end = false; break; } } } // 耗时程序,可以替换为自己的程序 public void test1() { DateTime dt1 = DateTime.Now; double step; while (true) { DateTime dt2 = DateTime.Now; step = dt2.Subtract(dt1).TotalSeconds; if (step > 12 ) { break; } } } // 进度条 private void startProgress() { // 显示进度条控件. progressBar1.Visible = true; // 设置进度条最小值. progressBar1.Minimum = 1; // 设置进度条最大值. progressBar1.Maximum = 15; // 设置进度条初始值 progressBar1.Value = 1; // 设置每次增加的步长 progressBar1.Step = 1; // 循环执行 int x = 0; while (x <= 15) { if (stop == true) { progressBar1.Value = 15; thread2.Abort(); break; } // 每次循环让程序休眠300毫秒 System.Threading.Thread.Sleep(300); // 执行PerformStep()函数 progressBar1.PerformStep(); if (x == 15) { x = 0; progressBar1.Value = 1; progressBar1.Step = 1; } x++; } } } }
需要注意,可能会报以下的错,此时只用把下面代码添加在Form启动的方法的后面即可。
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;