2012-09-05 12 views
5

Sé que es una pregunta similar en: ContinueWith a Task on the Main threadContinuar la tarea de hilo principal

pero esa pregunta es más hacia WPF y no puedo seeem para que funcione en una aplicación de consola.

Quiero ejecutar un método en un subproceso diferente y cuando se completa ese método quiero mantener la ejecución en el hilo principal. No quiero unirme al método. de todos modos aquí es lo que tengo:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Thread.CurrentThread.Name = "MAIN"; 

     DoWork(x => 
     { 
      Console.Write("Method successfully executed. Executing callback method in thread:" + 
       "\n" + Thread.CurrentThread.Name); 
     }); 

     Console.Read(); 
    } 

    static void DoWork(Action<bool> onCompleteCallback) 
    { 
     Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing 

     Task doWork = new Task(() => 
     { 
      Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing 
      Thread.Sleep(4000); 
     }); 

     Action<Task> onComplete = (task) => 
     {     
      onCompleteCallback(true); 
     }; 

     doWork.Start(); 

     // this line gives an error! 
     doWork.ContinueWith(onComplete, TaskScheduler.FromCurrentSynchronizationContext());      
    } 
} 

¿Cómo puedo ejecutar el método onCompleteCallback en el hilo principal?

+2

¿Por qué quiere/necesita hacer esto? –

+0

Buena pregunta. Estuve viendo algunos tutoriales y dónde tomar notas en una aplicación de consola. No pude hacer que funcione, así que básicamente hago esta pregunta para aprender. Pero supongo que no es necesario hacer esto. –

+1

Solo un FYI - esto se pone peor con 'async' /' await' - si llama a 'await' en una tarea en una aplicación de consola, cosas que no esperaría que ocurrieran :) Es debido a que este mismo problema ocurre bajo el capó –

Respuesta

6

pero esa pregunta es más hacia wpf y no puedo verla para que funcione en una aplicación de consola.

No puede hacer esto (sin mucho trabajo) en una aplicación de consola. Los mecanismos incorporados en el TPL para ordenar la devolución de la llamada a un hilo dependen todos de que el subproceso tenga un SynchronizationContext instalado. Normalmente, esto se instala mediante el marco de la interfaz de usuario (es decir: Application.Run en Windows Forms, o en el código de inicio de WPF, etc.).

En la mayoría de los casos, funciona porque el hilo principal tiene un bucle de mensaje, y el marco puede publicar un mensaje en el bucle de mensaje, que luego se recoge y ejecuta el código. Con una aplicación de consola, es solo un hilo "en bruto": no hay ningún bucle de mensaje donde se pueda colocar un mensaje.

Puede, por supuesto, instalar su propio contexto, pero eso va a agregar una gran cantidad de sobrecarga que probablemente no sea necesaria.


En una aplicación de consola, por lo general no es necesario "volver" al hilo de la consola. Normalmente, esperaría en la tarea, es decir:

class Program 
{ 
    static void Main(string[] args) 
    { 
     Thread.CurrentThread.Name = "MAIN"; 

     Task workTask = DoWork(); 

     workTask.Wait(); // Just wait, and the thread will continue 
         // when the work is complete 

     Console.Write("Method successfully executed. Executing callback method in thread:" + 
       "\n" + Thread.CurrentThread.Name); 
     Console.Read(); 
    } 

    static Task DoWork() 
    { 
     Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing 

     Task doWork = new Task(() => 
     { 
      Console.Write(Thread.CurrentThread.Name); // show on what thred we are executing 
      Thread.Sleep(4000); 
     }); 

     doWork.Start(); 

     return doWork; 
    } 
} 
+2

El otro problema es que el "hilo principal" nunca está ocupado haciendo algo para permitir que se vuelva a ejecutar alguna tarea de forma asíncrona. –

Cuestiones relacionadas