2010-09-22 87 views
16

我已經編寫了一個示例控制檯應用程序,以使用在此處發佈的其中一個示例在Stackoverflow中測試backgroundworker。我有一個背景工作,它以主要方法開始,但在操作過程中結束,如果我按下回車鍵,因爲我在主要方法中寫了一個console.readkey。但我希望它能夠等到背景工作者完成作業然後退出應用程序。這是我的代碼。如何等待BackgroundWorker完成,然後退出控制檯應用程序

class Program 
{ 
    private static BackgroundWorker worker = new BackgroundWorker(); 
    private event EventHandler BackgroundWorkFinished; 

    static void Main(string[] args) 
    { 
     worker.DoWork += worker_DoWork; 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
     worker.ProgressChanged += worker_ProgressChanged; 
     worker.WorkerReportsProgress = true; 
     worker.WorkerSupportsCancellation = true; 

     Console.WriteLine("Starting Application..."); 

     worker.RunWorkerAsync(); 
     Console.ReadKey(); 
    } 

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     Console.WriteLine(e.ProgressPercentage.ToString()); 
    } 

    static void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Console.WriteLine("Starting to do some work now..."); 
     int i; 
     for (i = 1; i < 10; i++) 
     { 
      Thread.Sleep(1000); 
      worker.ReportProgress(Convert.ToInt32((100.0 * i)/10)); 
     } 

     e.Result = i; 
    } 

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("Value Of i = " + e.Result.ToString()); 
     Console.WriteLine("Done now..."); 
    } 
} 
+1

爲什麼你然後運行後臺進程異步?這似乎是你想要它同步運行... – 2010-09-22 10:30:13

+1

如何同步運行它..? – 2010-09-22 11:04:15

+0

可能重複的[如何等待BackgroundWorker取消?](http://stackoverflow.com/questions/123661/how-to-wait-for-a-backgroundworker-to-cancel) – 2014-03-01 10:20:28

回答

8

有關如何在BackgroundWorker與主線程之間進行通信的信息,請參閱How to wait for a BackgroundWorker to cancel?

基本上,您必須使用您在DoWork結束時設置的事件來表示DoWork已完成。然後,您在主線程中對該事件執行WaitOne()。

+0

我已添加新代碼作爲答案。但還是有一些問題。請幫忙。 – 2010-09-22 09:59:00

4

Bgw的主要目的是與Windows MessageQueue進行交互。換句話說,它在WinForms和WPF應用程序中最爲有用。

控制檯應用程序不適合使用或測試Bgw。你會得到奇怪的結果。在關鍵點打印ManagedThreadId以查看會發生什麼。

還有一些標準的建議:你的worker_RunWorkerCompleted()應該檢查e.Error 現在它與具有空的 catch{}塊相同。
當您閱讀e.Result時,DoWork出現的任何錯誤現在都會拋出,處理起來比較複雜。

2

這就是我現在所做的。但console.readkey()不起作用。該應用程序不在等待ReadKey()函數。

class Program 
{ 
    private static BackgroundWorker worker = new System.ComponentModel.BackgroundWorker(); 
    private static AutoResetEvent resetEvent = new AutoResetEvent(false); 
    static void Main(string[] args) 
    { 
     worker.DoWork += worker_DoWork; 
     worker.RunWorkerCompleted += worker_RunWorkerCompleted; 
     worker.ProgressChanged += worker_ProgressChanged; 
     worker.WorkerReportsProgress = true; 

     Console.WriteLine("Starting Application..."); 

     worker.RunWorkerAsync(); 
     resetEvent.WaitOne(); 

     Console.ReadKey(); 
    } 

    static void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     Console.WriteLine(e.ProgressPercentage.ToString()); 
    } 

    static void worker_DoWork(object sender, DoWorkEventArgs e) 
    { 
     Console.WriteLine("Starting to do some work now..."); 
     int i; 
     for (i = 1; i < 10; i++) 
     { 
      Thread.Sleep(1000); 
      worker.ReportProgress(Convert.ToInt32((100.0 * i)/10)); 
     } 

     e.Result = i; 

     resetEvent.Set(); 
    } 

    static void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     Console.WriteLine("Value Of i = " + e.Result.ToString()); 
     Console.WriteLine("Done now..."); 
    } 

} 

固定編輯:感動resetEvent.Set()裏面DoWork的而非RunWorkerCompleted已完成事件處理程序將永遠不會被調用,因爲主線程正在等待事件。

+0

如果我在Windows 7的VS2008中使用.NET 3.5 SP1的控制檯項目中使用此代碼,它適用於我。 – 2010-09-22 10:33:55

+0

在Windows XP的VS2008中不適用於我。 – 2010-09-22 12:10:01

+0

請幫忙.... – 2010-09-22 12:18:54

相關問題