使用BackgroundWorker

1,WPF應用程序爲單線程模型(STAThread),全部UI控件都是主線程建立的,只有主線程能操做UI元素的顯示。異步

2,其餘工做線程要維護UI控件的顯示,需調用主線程的Dispather,執行Invoke(同步)或BeginInvoke(異步)方法。this

3,UI線程如時行耗時的操做,將使UI假死,用戶體驗較差。應使用後臺線程進行耗時操做,並異步更新UI。spa

4,BackgroundWorker是WPF的一個後臺工做類,代碼說明一切:線程

前臺:code

    <StackPanel>
        <ProgressBar Name="progressBar" Height="20" Width="200" Margin="10"></ProgressBar>
        <Button Name="btnProcess" Width="100" Click="btnProcess_Click" Margin="5">開始後臺任務</Button>
        <Button Name="btnCancel" Width="100" Click="btnCancel_Click" Margin="5">取消後臺任務</Button>
    </StackPanel>

後臺:blog

 public partial class MainWindow : Window
    {
        BackgroundWorker bgWorker = new BackgroundWorker();
        public MainWindow()
        {
            InitializeComponent();

            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;
            bgWorker.DoWork += DoWork_Handler;
            bgWorker.ProgressChanged += ProgressChanged_Handler;
            bgWorker.RunWorkerCompleted += RunWorkerCompleted_Handler;
        }

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

        private void ProgressChanged_Handler(object sender, ProgressChangedEventArgs args)
        {
               progressBar.Value = args.ProgressPercentage;
           
        }

        //後臺線程運行的程序
        private void DoWork_Handler(object sender, DoWorkEventArgs args)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            for (int i = 1; i <= 100; i++)
            {
                if (worker.CancellationPending)
                {
                    args.Cancel = true;
                    break;
                }
                else
                {
                    worker.ReportProgress(i);

                    //由於這在後臺線程,要想直接修改UI控件,需用Invoke或BeginInvoke方法
                    //this.Dispatcher.Invoke(new Action(() =>
                    //{
                    //    progressBar.Value = i;
                    //}));

                    Thread.Sleep(100);  //由於頻繁調用UI線程,爲了給UI線程反應時間,這裏讓後臺線程稍頓一下
                }
            }

        }

        private void RunWorkerCompleted_Handler(object sender, RunWorkerCompletedEventArgs args)
        {
            progressBar.Value = 0;
            if (args.Cancelled)
            {
                MessageBox.Show("後臺任務已經被取消。", "消息");
            }
            else
            {
                MessageBox.Show("後臺任務正常結束。", "消息");
            }
        }
        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            bgWorker.CancelAsync();
        }
    }
相關文章
相關標籤/搜索