2010-09-22 34 views
16

He escrito una aplicación de consola de muestra para probar backgroundworker usando uno de los ejemplos publicados aquí en Stackoverflow. Tengo un backgroundworker que comienza con el método main pero termina en el medio de la operación si presiono enter porque escribí console.readkey en el método main. Pero quiero que espere hasta que el backgroundworker haya terminado de hacer el trabajo y luego salga de la aplicación. Este es mi códigoCómo esperar a que BackgroundWorker termine y luego salir de la aplicación de consola

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

¿Por qué luego ejecuta el proceso de fondo Async? Parece que quieres que se ejecute sincrónicamente ... –

+1

Cómo ejecutarlo sincrónicamente ... ??? –

+0

posible duplicado de [¿Cómo esperar a que un BackgroundWorker se cancele?] (Http://stackoverflow.com/questions/123661/how-to-wait-for-a-backgroundworker-to-cancel) –

Respuesta

8

Consulte la publicación How to wait for a BackgroundWorker to cancel? para saber cómo comunicarse entre su BackgroundWorker y su hilo principal.

Básicamente, debe usar un evento que haya configurado al final de DoWork para indicar que DoWork se ha completado. A continuación, WaitOne() en ese evento en su hilo principal.

+0

He añadido el nuevo código como respuesta. Pero todavía hay algún problema. Por favor ayuda. –

4

El objetivo principal de un Bgw es interactuar con el Windows MessageQueue. En otras palabras, es más útil en aplicaciones WinForms y WPF.

Una aplicación de consola no es el lugar adecuado para usar o probar un Bgw. Obtendrás resultados extraños. Imprima ManagedThreadId en los puntos clave para ver qué sucede.

Y algunos consejos estándar: Su worker_RunWorkerCompleted() debe marcar e.Error. Ahora mismo es lo mismo que tener un bloque catch{} vacío.
Cualquier error de DoWork ahora se producirá cuando lea e.Result, más complejo de manejar.

2

Esto es lo que he hecho ahora. Pero el console.readkey() no funciona. La aplicación no está esperando la función 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..."); 
    } 

} 

fijación Editar:resetEvent.Set() se ha llevado a dentro DoWork en lugar de en RunWorkerCompleted. El controlador de eventos Completed nunca se llamará porque el hilo principal está esperando el evento.

+0

Si utilizo este código en un proyecto de consola en VS2008 con .NET 3.5 SP1 en Windows 7, me funciona. –

+0

No funciona para mí en VS2008 en Windows XP. –

+0

Por favor, ayuda ... –

Cuestiones relacionadas