BackgroundWorker 是 .NET Framework 中一个简化异步操作的组件,它位于 System.ComponentModel
命名空间下。它为开发人员提供了一种简单的方式在后台执行耗时操作,同时保持与 UI 线程的交互
主要属性以及任务如下:
DoWork 事件:在后台线程中执行耗时操作:(不能直接调用UI控件)
RunWorkerAsync 方法:启动后台操作
ReportProgress 方法:报告操作进度
ProgressChanged 事件:当进度更新时触发:(可以直接调用UI控件)
RunWorkerCompleted 事件:当操作完成时触发(可以直接调用UI控件)
CancellationPending 属性:检查是否请求取消
CancelAsync 方法:请求取消操作
IsBusy 属性:指示是否正在运行后台操作
注意事项:
在 DoWork 事件处理程序中不要直接访问UI控件
如果需要传递数据,可以使用
RunWorkerAsync(object)
和DoWorkEventArgs.Argument
结果可以通过
RunWorkerCompletedEventArgs.Result
传递回UI线程
例如:下面是一个wpf的小例子,仿真了开始,取消,以及汇报进度的功能。
public partial class BackgroundDemo : Window
{
BackgroundWorker bw;
public BackgroundDemo()
{
InitializeComponent();
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.DoWork += Bw_DoWork;
bw.ProgressChanged += Bw_ProgressChanged;
bw.RunWorkerCompleted += Bw_RunWorkerCompleted;
btnCancel.IsEnabled = false;
}
private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pbPercent.Value = 100;
this.btnCancel.IsEnabled = false;
this.btnStart.IsEnabled = true;
if(e.Error!=null)
{
this.tbInfo.Text = "异常" + e.Error.Message;
}
else if(e.Cancelled)
{
this.tbInfo.Text = "被取消";
}
else
{
this.tbInfo.Text = "正常完成";
}
}
private void Bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.pbPercent.Value = e.ProgressPercentage;
}
private void Bw_DoWork(object sender, DoWorkEventArgs e)
{
int timer =(int) e.Argument;
if (timer <= 0) timer = 20;
for(int i=0;i<timer;i++)
{
if(bw.CancellationPending)
{
e.Cancel = true;
break;
}
Thread.Sleep(1000);
bw.ReportProgress( i*100 / timer);
}
}
private void btnStart_Click(object sender, RoutedEventArgs e)
{
this.btnStart.IsEnabled = false;
this.btnCancel.IsEnabled = true;
bw.RunWorkerAsync(10); //运行20秒
this.tbInfo.Text = "开始计时中";
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
bw.CancelAsync();
}
}
<Window x:Class="AHui_ProjectManager.Model.BackgroundDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AHui_ProjectManager.Model"
mc:Ignorable="d"
Title="BackgroundDemo" Height="450" Width="800">
<Grid>
<TextBlock x:Name="tbInfo" HorizontalAlignment="Left" Height="23" Background="LightBlue"
Margin="0,50,0,0" VerticalAlignment="top" Width="381"/>
<ProgressBar x:Name="pbPercent" HorizontalAlignment="Left" Height="23"
Margin="0,90,0,0" VerticalAlignment="top" Width="381"/>
<Button x:Name="btnStart" Content="开始" HorizontalAlignment="Left" Height="23"
Margin="0,135,0,0" VerticalAlignment="top" Width="60" Click="btnStart_Click"/>
<Button x:Name="btnCancel" Content="取消" HorizontalAlignment="Left" Height="23"
Margin="306,135,0,0" VerticalAlignment="top" Width="60" Click="btnCancel_Click"/>
</Grid>
</Window>