c# - winform多线程进度条实现(progressBar工具)

0

  由于程序计算耗时较长,需要在耗时的地方加入循环滚动的进度条,经过学习和测试,分享一种Winform加载进度条的方法,经过验证可以达到既定需要,暂时没遇到明显报错,这里将实现过程与代码进行分享。

  1. 创建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++;
            }
        }
  1. 在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;