http://msdn.microsoft.com/zh-cn/library/cc221403(v=vs.95).aspx
如何:使用后台辅助线程
Silverlight BackgroundWorker 类提供通过后台线程运行非常耗时的操作的便利方法。BackgroundWorker 类允许您查看操作的状态并且可以取消操作。
使用 BackgroundWorker 类时,可以在 Silverlight 用户界面中指示操作进度、完成和取消情况。例如,可以查看后台操作是已完成还是已取消并为用户显示消息。
使用 BackgroundWorker 类
-
在类级别创建 BackgroundWorker 类的实例。
-
指定是否希望后台操作允许执行取消操作和报告进度。
-
为后台辅助线程的 DoWork 事件创建事件处理程序。
DoWork 事件处理程序位于在后台线程运行非常耗时的操作的位置。应在 DoWorkEventArgs 对象的 Argument 属性中传递要传递给后台操作的任何值,而该属性将传递给事件处理程序。
若要将进度报告回调用进程,请调用 ReportProgress 方法并将介于 0 到 100 之间的完成百分比传递给它。调用 ReportProgress 方法将引发 ProgressChanged 事件,您将单独处理该事件。
说明:
如果后台辅助线程的 WorkerReportsProgress 属性未设置为 true 且调用了 ReportProgress 方法,将引发异常。
若要确定是否有取消后台操作的挂起的请求,请查看 BackgroundWorker 对象的 CancellationPending 属性。如果该属性为 true,则表示调用了 CancelAsync 方法。将 BackgroundWorker 对象的 Cancel 属性设置为 true 并停止操作。
若要将数据传递回调用进程,请设置要传递给事件处理程序的 DoWorkEventArgs 对象的 Result 属性。在操作结束引发 RunWorkerCompleted 事件时,可以读取此值。
C#private void bw_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; (i <= 10); i++) { if ((worker.CancellationPending == true)) { e.Cancel = true; break; } else { // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); worker.ReportProgress((i * 10)); } } }
-
为后台辅助线程的 ProgressChanged 事件创建事件处理程序。
在 ProgressChanged 事件处理程序中,添加指示进度的代码(如更新用户界面)。
若要确定操作的完成百分比,请查看传递给事件处理程序的 ProgressChangedEventArgs 对象的 ProgressPercentage 属性。
-
为 RunWorkerCompleted 事件创建一个事件处理程序。
后台辅助线程完成时,将引发 RunWorkerCompleted 事件。根据后台操作是成功完成、遇到错误还是已取消,相应更新用户界面。
若要确定是否出错,请查看传递给事件处理程序的 RunWorkerCompletedEventArgs 对象的 Error 属性。如果出错,此属性将包含异常信息。
如果后台操作允许取消且您想查看操作是否被取消,请查看传递给事件处理程序的 RunWorkerCompletedEventArgs 对象的 Cancelled 属性。如果该属性为 true,则表示调用了 CancelAsync 方法。
-
为 BackgroundWorker 实例的事件添加事件处理程序。
下面的示例演示如何为 DoWork、ProgressChanged 和 RunWorkerCompleted 事件添加事件处理程序。
-
通过调用 RunWorkerAsync 方法来开始运行后台操作。
-
通过调用 CancelAsync 方法来取消后台操作。
下面的示例演示如何使用 BackgroundWorker 类。在此示例中,后台操作运行 Sleep 方法并将进度报告给用户界面。后台辅助线程已配置为允许取消。
using System.ComponentModel; using System.Windows; using System.Windows.Controls; namespace SL_BackgroundWorker_CS { public partial class Page : UserControl { private BackgroundWorker bw = new BackgroundWorker(); public Page() { InitializeComponent(); bw.WorkerReportsProgress = true; bw.WorkerSupportsCancellation = true; bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); } private void buttonStart_Click(object sender, RoutedEventArgs e) { if (bw.IsBusy != true) { bw.RunWorkerAsync(); } } private void buttonCancel_Click(object sender, RoutedEventArgs e) { if (bw.WorkerSupportsCancellation == true) { bw.CancelAsync(); } } private void bw_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; for (int i = 1; (i <= 10); i++) { if ((worker.CancellationPending == true)) { e.Cancel = true; break; } else { // Perform a time consuming operation and report progress. System.Threading.Thread.Sleep(500); worker.ReportProgress((i * 10)); } } } private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if ((e.Cancelled == true)) { this.tbProgress.Text = "Canceled!"; } else if (!(e.Error == null)) { this.tbProgress.Text = ("Error: " + e.Error.Message); } else { this.tbProgress.Text = "Done!"; } } private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) { this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%"); } } }
<UserControl x:Class="SL_BackgroundWorker_CS.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel Height="30" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" > <Button x:Name="buttonStart" Content="Start" Click="buttonStart_Click" Width="80" Height="30"/> <Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click" Width="80" Height="30"/> </StackPanel> <StackPanel Margin="10,50,0,0" Orientation="Horizontal"> <TextBlock Text="Progress: "/> <TextBlock x:Name="tbProgress"/> </StackPanel> </Grid> </UserControl>
<UserControl x:Class="SL_BackgroundWorker_VB.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="White"> <StackPanel Height="30" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10" > <Button x:Name="buttonStart" Content="Start" Click="buttonStart_Click" Width="80" Height="30"/> <Button x:Name="buttonCancel" Content="Cancel" Click="buttonCancel_Click" Width="80" Height="30"/> </StackPanel> <StackPanel Margin="10,50,0,0" Orientation="Horizontal"> <TextBlock Text="Progress: " /> <TextBlock x:Name="tbProgress" /> </StackPanel> </Grid> </UserControl>