关于在处理过程中ProgressBar显示进度的问题
我现在有一个大概15秒的处理过程,这15秒程序会像假死一样,现在我希望用ProgressBar先来显示进度,请问该怎么写? --------------------编程问答-------------------- 使用一个代理改变ProgressBar的进度 --------------------编程问答-------------------- 循环的话加上DoEvents,否则需要用多线程。 --------------------编程问答-------------------- 不是很懂哇。。。具体怎么搞。。。 --------------------编程问答-------------------- 直接在界面线程中 边循环处理数据 边改变进度条的value 加DoEvents后台线程中边处理数据 边改变进度条的value的话 需要代理 InvokeRequired
网上查一下 非UI线程操作UI控件
--------------------编程问答-------------------- 使用异步委托
在WinForm开发中,在处理大量数据时不免会有耗时较长的操作,如果将这些操作放在主线程里,软件界面会有较长时间的“无响应”,降低了用户体验,常用的解决方式是加上进度条。
实现思路
________________________________________
使用BackgroundWorker(已经封装好的线程工具)控件在后台线程执行费时的操作,在主线程中打开一个进度条窗体显示进度。
实现步骤
________________________________________
第0步:创建一个具有进度条的窗体,以显示进度
新建窗体ProcessForm,设置属性FormBorderStyle为None,添加一个ProcessBar控件,
PrcessBar的Style属性设置为MarQuee。在ProcessForm添加如下公共属性:
/// <summary>
/// 设置提示信息
/// </summary>
public string MessageInfo
{
set { this.labelInfor.Text = value; }
}
/// <summary>
/// 设置进度条显示值
/// </summary>
public int ProcessValue
{
set { this.progressBar1.Value = value; }
}
/// <summary>
/// 设置进度条样式
/// </summary>
public ProgressBarStyle ProcessStyle
{
set { this.progressBar1.Style = value; }
}
第1步:创建进度条管理类ProcessOperator
在该类中添加如下字段:
private BackgroundWorker _backgroundWorker;//后台线程
private ProcessForm _processForm;//进度条窗体
添加如下公共属性、方法和事件:
#region 公共方法、属性、事件
/// <summary>
/// 后台执行的操作
/// </summary>
public Action BackgroundWork { get; set; }
/// <summary>
/// 设置进度条显示的提示信息
/// </summary>
public string MessageInfo
{
set { _processForm.MessageInfo = value; }
}
/// <summary>
/// 后台任务执行完毕后事件
/// </summary>
public event EventHandler<EventArgs> BackgroundWorkerCompleted;
/// <summary>
/// 开始执行
/// </summary>
public void Start()
{
_backgroundWorker.RunWorkerAsync();
_processForm.ShowDialog();
}
#endregion
其中,属性BackgroundWork可以指向一个无参数的方法,这里(客户端代码)用来指向要在后台执行的费时操作方法,在_backgroundWorker的事件DoWork中调用该委托指向的方法
//后台执行的操作
private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (BackgroundWork != null)
{
BackgroundWork();
}
}
public void Start() 为启动进度条的方法,调用该方法后,会在后台线程(_backgroundWorker.RunWorkerAsync(); )中执行费时操作(DoWork事件中的委托指向的方法)。同时,_processForm.ShowDialog()方法负责打开进度条窗体。
当后台方法执行完毕后,会触发backgroundWorker的RunWorkerCompleted事件,在该事件中关闭进度条窗体
//操作进行完毕后关闭进度条窗体
private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (_processForm.Visible == true)
{
_processForm.Close();
}
if (this.BackgroundWorkerCompleted != null)
{
this.BackgroundWorkerCompleted(null, null);
}
}
以下是完整的ProcessOperator类代码:
/*
* author:Joey Zhao
* date:2010-11-30
* describe:进度条,该类可以在后台线程处理一些费时操作,并显示进度条,进度条并未真实显示数据进度
* 仅仅是告诉用户程序还活着,有待加强。使用方法:
* 1, 实例化一个ProcessOperator对象;
* 2,赋值BackgroundWork(类型为一个无参数无返回值的委托)属性为要在后台执行的方法(无参数无返回值的方法)
* 3,调用Start方法开始执行
* 4, 在事件BackgroundWorkerCompleted中执行后台任务完成后的操作
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Sasp.Client.PublicUnits.Process
{
public class ProcessOperator
{
private BackgroundWorker _backgroundWorker;//后台线程
private ProcessForm _processForm;//进度条窗体
public ProcessOperator()
{
_backgroundWorker = new BackgroundWorker();
_processForm = new ProcessForm();
_backgroundWorker.DoWork += new DoWorkEventHandler(_backgroundWorker_DoWork);
_backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);
}
//操作进行完毕后关闭进度条窗体
private void _backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (_processForm.Visible == true)
{
_processForm.Close();
}
if (this.BackgroundWorkerCompleted != null)
{
this.BackgroundWorkerCompleted(null, null);
}
}
//后台执行的操作
private void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (BackgroundWork != null)
{
BackgroundWork();
}
}
#region 公共方法、属性、事件
/// <summary>
/// 后台执行的操作
/// </summary>
public Action BackgroundWork { get; set; }
/// <summary>
/// 设置进度条显示的提示信息
/// </summary>
public string MessageInfo
{
set { _processForm.MessageInfo = value; }
}
/// <summary>
/// 后台任务执行完毕后事件
/// </summary>
public event EventHandler<EventArgs> BackgroundWorkerCompleted;
/// <summary>
/// 开始执行
/// </summary>
public void Start()
{
_backgroundWorker.RunWorkerAsync();
_processForm.ShowDialog();
}
#endregion
}
}
第2步:客户端代码调用
PercentProcessOperator p = new PercentProcessOperator();
p.BackgroundWork = this.LoadData;
p.BackgroundWorkerCompleted += new EventHandler<EventArgs>(p_BackgroundWorkerCompleted);
p.Start();
--------------------编程问答-------------------- 在循环中加上DoEvents处理消息.缺点是根据消息的多少会影响执行速度.
最好是开后台线程干活前台线程显示进度条.不过那个要在两个线程间传送进度信息.
略麻烦. --------------------编程问答--------------------
++
补充:.NET技术 , C#