"BackgroundWorker" 类允许您在单独的专用线程上运行操作。 耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用"BackgroundWorker" 类方便地解决问题。
若要在后台执行耗时的操作,请创建一个 "BackgroundWorker",侦听那些报告操作进度并在操作完成时发出信号的事件。 若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。 在此事件处理程序中调用耗时的操作。若要开始此操作,请调用 RunWorkerAsync。
若要收到进度更新的通知,请处理 ProgressChanged 事件,一般在DoWork中则可以调用 ReportProgress 方法来引发 ProgressChanged 事件。
若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。
您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。 而应该通过 ProgressChanged 和RunWorkerCompleted 事件与用户界面进行通信。
BackgroundWorker 事件不跨 AppDomain 边界进行封送处理。 请不要使用 BackgroundWorker 组件在多个 AppDomain 中执行多线程操作。
当BackgroundWorker对象开始执行后,它从CLR线程池提出一个自由线程,然后从这个线程引发DoWork事件。您可以处理DoWork事件并开始执行耗时任务。
但需要谨慎地访问共享数据(如窗口类中的字段)和用户界面。一旦完成了工作,BackgroundWorker对象就会引发RunWorkerCompleted事件以通知应用程序。
一旦完成了工作,BackgroundWorker对象就会引发RunWorkerCompleted事件以通知应用程序。这个事件在调度程序线程引发,在该线程中您可以访问共享数据和用户界面,
而不会导致任何问题。
"不需要任何加锁代码,并且和ui交互不需要使用Dispather.BeginInvoke()方法。BackgroundWorker对象使用的是.NET 2.0版中引入的多线程类",而如果使用Thread则
需要BeginInvoke,委托来处理和界面的交互,而且还需要加锁,防止死锁。C#中用BackgroundWorker更方便。
一般如果你要在后台长时间地运行任务且希望与ui有互操作,那用backgroundworker.
"报告进度:" 如果您需要后台操作报告其进度,则可以调用 ReportProgress 方法来引发 ProgressChanged 事件。
WorkerReportsProgress 属性值必须是 true,否则 ReportProgress 将引发 InvalidOperationException。 您需要实现一个有意义的方法,以便按照占已完成的总任务的百分比来度量后台操作的进度。
提供和显示执行进度信息是两个步骤。首先,DoWorker事件处理代码需要调用BackgroundWorker.ReportProgress()方法。
提供一个已经完成的百分比(从0到100%)。每次调用ReportProgress()方法时,BackgroundWorker对象都会引发ProgressChanged
事件。可以响应该事件,读取新的百分比并更新用户界面。因为ProgressChanged事件是从用户界面引发的,所有不需要使用Dispather.BeginInvoke()方法。
例子,经过验证:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Timers;
using System.Threading;
using System.Windows.Threading;
using System.ComponentModel; //BackgroundWorker的工作空间
using System.Diagnostics;
namespace WpfApplication1
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
//public Timer timer;
public int i;
public int j;
BackgroundWorker backWork;
public MainWindow()
{
j=10;
this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
backWork = new BackgroundWorker();
backWork.WorkerReportsProgress = true;
backWork.ProgressChanged += new ProgressChangedEventHandler(backWork_ProgressChanged);
backWork.DoWork += new DoWorkEventHandler(backWork_DoWork);
backWork.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backWork_RunWorkerCompleted);
//j为传入到DoWorker中的参数
backWork.RunWorkerAsync(j);
Trace.WriteLine("backwork");
i = 0;
InitializeComponent();
}
void backWork_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Trace.WriteLine(e.ProgressPercentage.ToString());
}
void backWork_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Trace.WriteLine("运行结束后的值:"+ e.Result.ToString());
}
void backWork_DoWork(object sender, DoWorkEventArgs e)
{
Trace.WriteLine("backwork begin work!");
Trace.WriteLine(e.Argument.ToString());
for(int i = 0 ;i<100;i++)
{
System.Threading.Thread.Sleep(50);
backWork.ReportProgress(i); //此处会引发backWork_ProgressChanged事件
}
e.Result = 55;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
}
}
}