C# Tips之进度条

本文深入解析C#中进度条控件的工作原理及其实现方法,介绍如何利用progressbar控件反映流程进度,探讨其属性及多线程下如何更新进度条值。

写在前面

C# Tips是博主开启的第一个项目,以C#为示例语言,旨在普及编程技巧、经典算法以及计算机视觉、图形学知识。

进度条的日常

只要是接触过计算机的同学,对于进度条一定不陌生。
有时候它是这样的(图片来自网络):
炫酷的进度条
有时候是这样的(图片来自网络):
缓慢的进度条
那么疑问来了,为什么有的进度条能学会“百米冲刺”,而有的进度条却像乌龟一样缓缓前行?为解决这个疑问,需要了解进度条的含义以及工作机制,然后我们可以利用VS的progress bar控件轻松定义属于自己的进度条。

进度条的含义

进度条是一种定量反映流程进度的控件。进度条的增加速度体现了走完流程所耗费的时间,进度条的增加次数体现了完成流程所需的步骤,进度条本身的数值体现了当前所完成的进度。

为实现以上要求,C#中progress bar控件拥有以下属性:

属性含义
Minimum进度条范围的最小值(进度条完全未填满状态)
Maximum进度条范围的最大值(进度条完全填满状态)
Value进度条当前值

进度条的工作机制

为了更好地量化时间流逝,progress bar将开启流程的时间记为Minimum(通常为0),结束流程的时间记为Maximum,Maximum-Minimum即为走完流程所耗费的等价时间,或者将Maximum理解为流程能够拆解的步骤数量,每完成一个步骤,Value便增加n个单位的时间,每一个单位时间表示的实际时间不尽相同,与完成上一个步骤所需的实际时间有关。

Created with Raphaël 2.2.0 开始 Value=Minimum 完成一个步骤 Value+=n Value>=Maximum? 结束 yes no

进度条的实现

与按钮、文本等控件不同,progress bar需要实时更新,放置在主窗体的控件会因为主线程(UI线程)阻塞而无法及时更新,所以最好的做法是将耗时方法放到另外一个线程中,然后根据另一个线程中耗时方法的执行进度更新主线程中progress bar的Value值。

但由此会引发两个问题:

  1. 如何创建另一个线程?
  2. 非主线程该怎么控制主线程中的控件才不会出错呢?

多线程问题

C#在System.Threading中提供了一系列创建线程的方法:

开启线程的方法Method返回值必须为void,参数为object类型或无参,如果需要传递多个参数,可将参数封装到类或结构体中,直接传入对象即可。

private void Method(object parameters)
Thread thread1 = new Thread(new ParameterizedThreadStart(Method));
thread1.IsBackground = true;
thread1.Start(parameters);

或者

private void Method()
Thread thread1 = new Thread(new ThreadStart(Method));
thread1.IsBackground = true;
thread1.Start();

跨线程问题

为解决第二个问题,首先定义一个设置progress bar值的委托:

private delegate void pbDelegate(int value);

然后再写一个包含Control.Invoke的方法:

/// <summary>
/// 多线程设置进度条的值
/// </summary>
/// <param name="value">值</param>
private void SetPbValue(int value)
{
    if (progressBar1.InvokeRequired)
        Invoke(new pbDelegate(SetPbValue), new object[] { value });
    else
    {
        if (value != -1)
            progressBar1.Value = value;
        else
            progressBar1.Visible = false;
    }
}

上面代码的含义是:

  1. 如果progress bar在主线程中,直接更新progress bar的值,当值为-1时指示progress bar不可见;
  2. 如果progress bar在非主线程中,利用Invoke执行委托,效果将会与在主线程中一致。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值