如何使用WPF的后台工作

我是WPF的初学者,在我的应用程序中,我需要执行一系列的初始化步骤,这些需要7-8秒才能完成,在这个过程中,我的UI变得没有反应。 为了解决这个问题,我在一个单独的线程中执行初始化:

public void Initialization() { Thread initThread = new Thread(new ThreadStart(InitializationThread)); initThread.Start(); } public void InitializationThread() { outputMessage("Initializing..."); //DO INITIALIZATION outputMessage("Initialization Complete"); } 

我已经阅读了关于BackgroundWorker的一些文章,以及它如何让我保持我的应用程序响应,而不必写一个线程来执行冗长的任务,但我没有尝试实现它的任何成功,谁能告诉我如何使用BackgroundWorker做到这一点?

谢谢,Eamonn

1.添加以下使用: using System.ComponentModel;

2.Declare 后台工作者 :

 private readonly BackgroundWorker worker = new BackgroundWorker(); 

3.订阅活动:

 worker.DoWork += worker_DoWork; worker.RunWorkerCompleted += worker_RunWorkerCompleted; 

4.实施两种方法:

 private void worker_DoWork(object sender, DoWorkEventArgs e) { // run all background tasks here } private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //update ui once worker complete his work } 

5.只要你需要,你就可以工作。

 worker.RunWorkerAsync(); 

另外,如果要报告进程进度,则应订阅ProgressChanged事件并在DoWork方法中使用ReportProgress(Int32)来引发事件。 还设置如下: worker.WorkerReportsProgress = true; (感谢@zagy)

希望这个帮助。

你可能也想看看使用Task而不是后台工作人员。

在你的例子中最简单的方法是Task.Run(InitializationThread);

使用任务而不是后台工作者有几个好处。 例如,.net 4.5中的新异步/等待功能使用Task进行线程化。 这里是一些关于Task文档http://msdn.microsoft.com/en-us/library/system.threading.tasks.task(v=vs.110).aspx

 using System; using System.ComponentModel; using System.Threading; namespace BackGroundWorkerExample { class Program { private static BackgroundWorker backgroundWorker; static void Main(string[] args) { backgroundWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; backgroundWorker.DoWork += backgroundWorker_DoWork; //For the display of operation progress to UI. backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; //After the completation of operation. backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:"); Console.ReadLine(); if (backgroundWorker.IsBusy) { backgroundWorker.CancelAsync(); Console.ReadLine(); } } static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { for (int i = 0; i < 200; i++) { if (backgroundWorker.CancellationPending) { e.Cancel = true; return; } backgroundWorker.ReportProgress(i); Thread.Sleep(1000); e.Result = 1000; } } static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) { Console.WriteLine("Completed" + e.ProgressPercentage + "%"); } static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { Console.WriteLine("Operation Cancelled"); } else if (e.Error != null) { Console.WriteLine("Error in Process :" + e.Error); } else { Console.WriteLine("Operation Completed :" + e.Result); } } } } 

另外,请参阅下面的链接,您将了解Background的概念:

http://www.c-sharpcorner.com/UploadFile/1c8574/threads-in-wpf/

除了安德鲁·奥西奇(Andrew Orsich)所说的,也许你想读一些关于它的例子。

这里是使用后台工作人员和进度条的示例代码

http://devtoolshed.com/content/c-download-file-progress-bar

这里是一个小教程

http://www.dotnetperls.com/backgroundworker

在本教程的最后,还有另一个progressbar + backgroundworker例子的链接。

我发现这一点( WPF多线程:使用BackgroundWorker和向UI报告进度链接 )包含@ Andrew的答案中缺少的其他细节。

有一件事我发现非常有用的是工作线程不能访问MainWindow的控件(在它自己的方法中),但是当在主窗口事件处理程序中使用委托时,这是可能的。

 worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) { pd.Close(); // Get a result from the asynchronous worker T t = (t)args.Result this.ExampleControl.Text = t.BlaBla; }; 

在MSDN中尝试此链接BackgroundWorker类,其中包含如何使用它的示例。