【C#学习笔记】使用C#中BackgroundWorker

使用前提

在WPF程序中,有一些比较耗时的后台操作时,比如向远程服务器请求数据,或者通过TCP/IP为某台设备提供升级固件服务等等。为了防止这类操作freeze用户界面,造成用户体验下降,即程序假死的状况出现。一种常见的,更user friendly的方式是,提供一个进度条窗口,提示用户该操作的完成进度。并提供取消操作的选项。

C#中的 BackgroundWorker Class 则是执行该任务的最佳选择。

The BackgroundWorker class allows you to run an operation on a separate, dedicated thread. Time-consuming operations like downloads and database transactions can cause your user interface (UI) to seem as though it has stopped responding while they are running. When you want a responsive UI and you are faced with long delays associated with such operations, theBackgroundWorker class provides a convenient solution.
-MSDN

关于 BackgroundWorker 类

主要属性

  • CancellationPending - 只读属性,default值为false,执行CancelAsync方法后,值为true。表明应用程序请求了取消后台操作。
  • IsBusy - 如果后台异步操作开始执行,值为true,否则为false
  • WorkerReportProgress - 如果BackgroundWorker支持后台操作进程更新,设置值为true,default值为false

主要事件

  • DoWork
  • ProgressChanged
  • RunWorkerCompleted
    不要再DoWork事件处理程序中对UI线程中的对象进行操作,操作应该放在ProgressChanged和RunWorkerCompleted的事件处理程序中。

主要方法

  • RunWorkerAsync() - 执行后台操作,激发DoWork事件
  • ReportProgress()- 激发ProgressChanged事件
  • CancelAsync() - 提交终止后台操作的请求,并将CancellationPending属性值设为true。在程序其他地方要定时检查CancellationPending属性的值,作出相应操作,比如
if (worker.CancellationPending)
{
    e.Cancel = true;
}

示例程序

XAML


    
        
        
        
        
    

C#

namespace BackgroundWorkerExample
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        BackgroundWorker bgworker = new BackgroundWorker();
        public MainWindow()
        {
            InitializeComponent();

            bgworker.WorkerReportsProgress = true;
            bgworker.WorkerSupportsCancellation = true;
            bgworker.DoWork += bgworker_DoWork;
            bgworker.ProgressChanged += bgworker_ProgressChanged;
            bgworker.RunWorkerCompleted += bgworker_RunWorkerCompleted;
        }


        void bgworker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 1; i <= 100; i++)
            {
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                }
                else
                {
                    worker.ReportProgress(i);
                    Thread.Sleep(100);
                }
            }
        }
       
        void bgworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar.Value = e.ProgressPercentage;
            textBox.Text = e.ProgressPercentage.ToString();
        }

        void bgworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressBar.Value = 0;
            if (e.Cancelled)
            {
                MessageBox.Show("Background task has been canceled", "info");
            }
            else
            {
                MessageBox.Show("Background task finished", "info");
            }
        }

        private void btnProcess_Click(object sender, RoutedEventArgs e)
        {
            if (!bgworker.IsBusy)
            {
                bgworker.RunWorkerAsync();
            }
        }

        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            bgworker.CancelAsync();
        }
    }
}

演示

【C#学习笔记】使用C#中BackgroundWorker_第1张图片
BackgroundWorkerExample.gif

你可能感兴趣的:(【C#学习笔记】使用C#中BackgroundWorker)