backgroundWorker是一个非常好用的工具,可以实现异步执行耗时的操作并更新执行进度,防止界面挂起而不响应用户操作。
属性和事件介绍
/***** Form1.cs *****/
_bgWorker.WorkerReportsProgress = true; //是否上报执行进度
_bgWorker.WorkerSupportsCancellation = true;//是否可以取消
_bgWorker.DoWork += new DoWorkEventHandler(LongExecFun); //添加耗时的事件委托
_bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CallBackFun);//耗时执行结束后的回掉函数
_bgWorker.ProgressChanged += new ProgressChangedEventHandler(UpdateProgressFun);//耗时操作中上报执行进度时更新UI界面的函数
private void LongExecFun(object sender, DoWorkEventArgs e)
{
for(int i=0; i<10000<;i++)
{
_bgWorker.ReportProgress(i);
}
}
private void UpdateProgressFun(object sender, ProgressChangedEventArgs e)
{
label1.Text = e.ProgressPercentage.ToString();
}
private void CallBackFun(object sender, RunWorkerCompletedEventArgs e)
{
label1.Text="Exection Complete";
}
一般情况下,如果你的所有操作在同一个类中完成,这里非常简单,没有任何问题。但是如果你在Form1.cs中调用backgroundWork去执行另一个类(如 classA)中的耗时操作,却发现在classA中无法调用下面一句代码来上报进度,原因很简单因为_bgworker是在Form1类中申明的,不能再ClassA中调用。
_bgWorker.ReportProgress(i);
怎么办呢?总不至于在Form1类中声明一个ClassA类的实例,然后再到ClassA中申明一个Form1类的实例把,这样循环申明不见得管用。 可以在Form1中申明一个静态static函数来调用 _bgWorker.ReportProgress(i); 然后在ClassA中调用这个静态函数,由于静态函数是不需要申明Form1实例的,所以可以直接调用。
public static void UpdateProgress(int p)
{
_bgWorker.ReportProgress(p);//注意,这个_bgworker也要申明为static变量
}
最终代码如下:
/***** Form1.cs *****/
public static BackgroundWorker _bgWorker; //必须申明为static类型才能在static 函数中调用
_bgWorker.WorkerReportsProgress = true; //是否上报执行进度
_bgWorker.WorkerSupportsCancellation = true;//是否可以取消
_bgWorker.DoWork += new DoWorkEventHandler(LongExecFun); //添加耗时的事件委托
_bgWorker.ProgressChanged += new ProgressChangedEventHandler(UpdateProgressFun);//耗时操作中上报执行进度时更新UI界面的函数
ClassA ca = new ClassA();
_bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(ca.LongExecFun);//耗时执行结束后的回掉函数
private void UpdateProgressFun(object sender, ProgressChangedEventArgs e)
{
label1.Text = e.ProgressPercentage.ToString();
}
private void CallBackFun(object sender, RunWorkerCompletedEventArgs e)
{
label1.Text="Exection Complete";
}
public static void ReportProgress(int p)
{
_bgWorker.ReportProgress(i);
}
/****** ClassA *******/
private void LongExecFun(object sender, DoWorkEventArgs e)
{
for(int i=0; i<10000<;i++)
{
Form1.ReportProgress(int i*100/10000);//调用静态上报函数
}
}
这里只是提供了一种跨类使用backgroundWorker的一种方法,也许不是最好的方法,但是可以实现我们想要的功能。如果朋友们有更好的方法,还请不吝分享。