.NET WinForm中使用Timer定时更新ProgressBar的进度「建议收藏」

.NET WinForm中使用Timer定时更新ProgressBar的进度

大家好,又见面了,我是全栈君。

在.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定时器控件。因为,有的时候我们确实很难评估一个执行过程到底需要多少步骤或者需要多长时间才能完成。  

本文转自Jaxu博客园博客,原文链接:http://www.cnblogs.com/jaxu/archive/2011/08/05/2128811.html,如需转载请自行联系原作者


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107959.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • linux下如何保存退出vim编辑器

    linux下如何保存退出vim编辑器命令:vimapp.py如果不存在app.py则会自动创建1.进入编辑器后按字母“i”即可进入编辑状态(此时左下角会出现 “插入”)2.退出的时候分为4种情况:保存退出、正常退出、不保存退出以及强制退出 2.1:保存退出:按“Esc”键后此时的“插入”会消失,然后按Shift+zz就可以保存修改内容并退出 2.2:不保存退出:当修改修改了一部分内容后发现修改错了,此时就会进行不保存退…

    2022年6月3日
    239
  • noip2013普及组复赛答案_noip2020初赛

    noip2013普及组复赛答案_noip2020初赛Prob.1转圈游戏找到循环节,然后快速幂。代码:#include<cstdio>#include<cstring>#include<iostream>usingnamespacestd;intpos[1000005],vis[1000000];intn,m,k,x,p,mod;intpow(…

    2025年7月27日
    2
  • TCP的粘包解析「建议收藏」

    TCP的粘包解析「建议收藏」这两天看csdn有一些关于socket粘包,socket缓冲区设置的问题,发现自己不是很清楚,所以查资料了解记录一下: 一.两个简单概念长连接与短连接:1.长连接   Client方与Server方先建立通讯连接,连接建立后不断开,然后再进行报文发送和接收。2.短连接   Client方与Server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此

    2022年8月11日
    5
  • httprunner(3)用脚手架快速搭建项目[通俗易懂]

    httprunner(3)用脚手架快速搭建项目[通俗易懂]前言如何快速搭建一个httprunner项目呢?我们可以使用脚手架,脚手架就是自动地创建一些目录,形成一个项目的架构,不需要我们再手动的去创建查看创建新项目的命令先来查看一下帮助命令httpr

    2022年7月31日
    4
  • hadoop生态圈详解

    hadoop生态圈详解学习和使用hadoop有一年了,这里主要分享一下对hadoop整体上的理解,分门别类的介绍一下相关组件,最后提供了建议的学习路线,希望对hadoop的初学者有参考作用。1.Hadoop核心件组有哪些?广义hadoop指什么?l核心组件有:Hdfs、Yarn、MapReduce;l广义上指一个生态圈,泛指大数据技术相关的开源组件或产品,如hdfs、yarn、h…

    2022年5月22日
    48
  • Tomcat的安装与环境变量配置(图文详解)「建议收藏」

    Tomcat的安装与环境变量配置(图文详解)「建议收藏」Tomcat的下载安装与环境变量配置

    2022年6月12日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号