博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
.NET WinForm中使用Timer定时更新ProgressBar的进度
阅读量:6091 次
发布时间:2019-06-20

本文共 2762 字,大约阅读时间需要 9 分钟。

  在.NET WinForm程序中,大多数情况下我们是知道程序运行所需要的时间或步骤的,比如批量复制文件时文件的数量,数据导出或导入时数据的总行数等等。对于步骤比较确定的操作,如果程序执行过程时间较长,很容易使用BackgroundWorker结合ProgressBar来显示一个实时的进度。相关内容大家可以看我博客中的其它文章,有关如何使用BackgroundWorker和ProgressBar。但是,有的时候我们是不确定程序执行的具体步骤或时长的,比如连接一个远程服务或数据库服务,或者调用一个远程过程或WebService等,这个时候我们就没有办法去触发BackgroundWorker的ProgressChanged事件,因此也就不能实时去更新ProgressBar的进度了。有两种替代的办法可以解决这个问题。

  第一是将ProgressBar的Style设置为Marquee而不是默认的Blocks。在Marquee模式下,进度条会不停地向前走用来模拟一个长时间的操作。事实上,Windows中也有很多类似的进度条,大多都是出现在对操作过程所需的步骤和时长不太确定的时候。这种方法很简单,不过你仍然要将后台的执行过程放到多线程来执行,否则进度条会卡在UI线程中。一个好的办法就是依旧使用BackgroundWorker组建,将后台的执行程序放到BackgroundWorker的DoWorker事件中,然后调用BackgroundWorker的RunWorkerAsync方法来异步执行程序。这样,UI线程和后台执行程序的线程可以分开,进度条便不会再卡了。

  第二种方法是使用System.Windows.Forms.Timer定时器控件,设置好Timer的Interval间隔时间,在Timer的Tick事件中来更新ProgressBar的进度。由于Timer天生就是多线程的,所以这种办法实现起来很方便。

 1 
using
 System;
 2 
using
 System.Collections.Generic;
 3 
using
 System.ComponentModel;
 4 
using
 System.Data;
 5 
using
 System.Drawing;
 6 
using
 System.Linq;
 7 
using
 System.Text;
 8 
using
 System.Windows.Forms;
 9 
using
 System.Threading;
10 
11 
namespace
 WindowsFormsApplication2
12 
{
13 
    
public
 
partial
 
class
 Form1 : Form
14 
    {
15 
        
private
 BackgroundWorker worker 
=
 
new
 BackgroundWorker();
16 
        
private
 System.Windows.Forms.Timer timer 
=
 
new
 System.Windows.Forms.Timer();
17 
        
public
 Form1()
18 
        {
19 
            InitializeComponent();
20 
            
this
.progressBar1.Value 
=
 
0
;
21 
            
this
.progressBar1.Maximum 
=
 
200
;
22 
            
this
.progressBar1.Step 
=
 
1
;
23 
            timer.Interval 
=
 
100
;
24 
            timer.Tick 
+=
 
new
 EventHandler(timer_Tick);
25 
            worker.WorkerReportsProgress 
=
 
true
;
26 
            worker.DoWork 
+=
 
new
 DoWorkEventHandler(worker_DoWork);
27 
            worker.RunWorkerCompleted 
+=
 
new
 RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
28 
            worker.RunWorkerAsync();
29 
            timer.Start();
30 
        }
31 
32 
        
void
 timer_Tick(
object
 sender, EventArgs e)
33 
        {
34 
            
if
 (
this
.progressBar1.Value 
<
 
this
.progressBar1.Maximum)
35 
            {
36 
                
this
.progressBar1.PerformStep();
37 
            }
38 
        }
39 
40 
        
void
 worker_RunWorkerCompleted(
object
 sender, RunWorkerCompletedEventArgs e)
41 
        {
42 
            timer.Stop();
43 
            
this
.progressBar1.Value 
=
 
this
.progressBar1.Maximum;
44 
            MessageBox.Show(
"
Complete!
"
);
45 
        }
46 
47 
        
void
 worker_DoWork(
object
 sender, DoWorkEventArgs e)
48 
        {
49 
            
int
 count 
=
 
100
;
50 
            
for
 (
int
 i 
=
 
0
; i 
<
 count; i
++
)
51 
            {
52 
                Thread.Sleep(
100
);
53 
            }
54 
        }
55 
    }
56 
}

   Timer每隔100毫秒便调用一次Tick事件,在该事件中更新ProgressBar的当前进度。注意需要判断ProgressBar的Value必须小于Maximum值时才去执行Performance()方法,否则会出现ProgressBar的Value大于Maximum的值而抛异常。根据BackgroundWorker的DoWork方法执行所需的时间长短不同,ProgressBar的进度可能会在BackgroundWorker执行具体操作完成之前到达100%,也可以没有到达100%,所以在BackgroundWorker的RunWorkerCompleted事件中将ProgressBar的进度更新为100%,以确保进度在最后是一个完成的状态。

  如果你在应用程序中确实需要使用进度条来提示用户后台程序在完成一个耗时较长的操作,而且你还希望进度条能尽量模拟出程序执行的步骤,而不是一个Marquee状态,可以考虑使用Timer定时器控件。因为,有的时候我们确实很难评估一个执行过程到底需要多少步骤或者需要多长时间才能完成。  

转载地址:http://eylwa.baihongyu.com/

你可能感兴趣的文章
【Python】软件管理工具--pip
查看>>
插入排序之表插入排序
查看>>
Eclipse整合Tomcat开发Dynamic Web Project环境总结
查看>>
实战博客园访问流量计数器-三步操作简化教程
查看>>
JDBC与JAVA数据库编程
查看>>
Android开发之旅:环境搭建及HelloWorld
查看>>
Red Hat Enterprise Linux 各个版本以及发布日期
查看>>
J2EE全面介绍
查看>>
深入浅出Cocoa多线程编程之 block 与 dispatch quene
查看>>
UIWebView
查看>>
并发集合(三)使用阻塞线程安全的列表
查看>>
【机房合作】状态模式与上机
查看>>
iOS中alloc与init
查看>>
Raw Sockets programming on Linux with C
查看>>
纸上谈兵: AVL树[转]
查看>>
SpriteBuilder中粒子发射器的reset on visibility toggle选项解释
查看>>
深入浅出jackrabbit之十三 查询之AST和QT
查看>>
动态规划算法计算网络的最长路线和最短路线
查看>>
eclipse中ant build 控制台乱码解决解决方法(ant执行java)
查看>>
搭建Maven私服(使用Nexus)
查看>>