2011-10-27 9 views
21

¿Es este un buen diseño para un hilo de fondo que debe ejecutarse utilizando la API de tareas en .NET 4? Mi única preocupación es si queremos cancelar esa tarea, ¿cómo lo haría? Sé que puedo simplemente configurar ProgramEnding en true, pero sé que hay un CancellationToken en la API de tareas.Best Practice LongRunning Creación de tareas

Esto es solo una muestra de ejemplo de código para que un hilo se agregará a una colección y otro hilo se eliminará de ella. La tarea se configura como LongRunning ya que este debe estar en ejecución continua, mientras que el programa se está ejecutando

private void RemoveFromBlockingCollection() 
{ 
    while (!ProgramEnding) 
    { 
     foreach (var x in DataInQueue.GetConsumingEnumerable()) 
     { 
      Console.WriteLine("Task={0}, obj={1}, Thread={2}" 
          , Task.CurrentId, x + " Removed" 
          , Thread.CurrentThread.ManagedThreadId); 
     } 
    } 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    DataInQueue = new BlockingCollection<string>(); 
    var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection 
           , TaskCreationOptions.LongRunning); 

    for (int i = 0; i < 100; i++) 
    { 
    DataInQueue.Add(i.ToString()); 
    Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
         Task.CurrentId, i + " Added", 
         Thread.CurrentThread.ManagedThreadId); 
    Thread.Sleep(100); 
    } 
    ProgramEnding = true; 
} 

ACTUALIZACIÓN: He descubierto que puedo quitar el booleano ProgramEnding y utilizar DataInQueue.CompleteAdding el que el que llevar el hilo de un final.

Respuesta

18

Como ya lo mencionaste, puedes utilizar el CancelToken. Hacerlo de esta manera:

var cancellationTokenSource = new CancellationTokenSource(); 
Task.Factory.StartNew(RemoveFromBlockingCollection 
         , TaskCreationOptions.LongRunning 
         , cancellationTokenSource.Token); 

Y adelante en el código, puede cancelar la tarea con:

cancellationTokenSource.Cancel(); 

En su tarea en ejecución tiempo se puede pedir a la razón, si se solicitó la cancelación:

if (cancellationTokenSource.Token.IsCancellationRequested) 
+0

¿El uso de un booleano para mantener vivo el hilo es una mejor práctica o hay una llamada API? He descubierto que puedo usar el método CompleteAdding en un BlockingCollection, pero si no estoy usando un BlockingCollection y hago otra cosa, ¿el booleano puede ser acpelable? – Jon

+0

Sí, funcionaría. O utiliza el CancelToken que mencioné anteriormente. – Fischermaen

+0

Puedo usar eso para cancelar el hilo. Estaba pidiendo tu opinión para mantener un hilo ejecutándose. – Jon

Cuestiones relacionadas