2010-09-22 129 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

相关问题