如何:使用后台辅助线程
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 事件时,可以读取此值。
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>