2010-10-01 17 views
28

un código como el siguiente comenzará un nuevo hilo para hacer el trabajo. ¿Hay alguna manera de que pueda controlar la prioridad de ese hilo?bajando la prioridad de Task.Factory.StartNew thread

Task.Factory.StartNew(() => { 
    // everything here will be executed in a new thread. 
    // I want to set the priority of this thread to BelowNormal 
}); 

Respuesta

6

Esta es una de "no hacer" cuando se decide si se debe utilizar agrupación de hebras o no ;-)

Más detalles aquí: http://msdn.microsoft.com/en-us/library/0ka9477y.aspx

Así que la respuesta es "No, no puede especificar una prioridad especial para el hilo creado en Theads piscina"

a partir de roscas generales apuesto a que ya sabe acerca de la propiedad Thread.Priority

+3

Sí, sé sobre Thread.Priority. Pero solo quería saber si era posible con Task Factory en lugar de utilizar objetos de Thread. – Moon

+0

En el primer enlace hay una descripción que dice que no es posible con Task Factory.De todos modos, nunca tendré que cambiar la prioridad para los hilos del grupo y no estoy 100% seguro de que sea cierto. – zerkms

5

Para establecer la prioridad con Task, consulte los programadores de tareas personalizados descritos por el experto de Microsoft Stephen Toub en this MSDN blog post. Para obtener más detalles, no se pierda los enlaces a las dos publicaciones anteriores que menciona en la primera oración.

Para su problema, parece que podría querer mirar el QueuedTaskScheduler.

15

La prioridad del subproceso para las tareas se puede establecer dentro del método real que ejecuta la tarea. Pero no olvide restaurar la prioridad una vez que haya terminado para evitar problemas.

Así que primero iniciar la tarea:

new TaskFactory().StartNew(StartTaskMethod);

A continuación, establezca la prioridad de subprocesos:

void StartTaskMethod() 
{ 
    try 
    { 
     // Change the thread priority to the one required. 
     Thread.CurrentThread.Priority = ThreadPriority.AboveNormal; 

     // Execute the task logic. 
     DoSomething(); 
    } 
    finally 
    { 
     // Restore the thread default priority. 
     Thread.CurrentThread.Priority = ThreadPriority.Normal; 
    } 
} 

Al cambiar la prioridad, tenga en cuenta lo siguiente: Why *not* change the priority of a ThreadPool (or Task) thread?

+6

Este enfoque me parece peligroso. ¿No es eso establecer la prioridad en uno de los hilos de ThreadPool? No sabes dónde se usará ese hilo a continuación. – Brannon

+0

@Brannon, cambiar la prioridad a través del Programador de tareas tendrá un efecto similar, supongo. En general, no cambia la prioridad en absoluto, pero si necesita hacer esto, no hay diferencia de cómo lo hace. –

+1

@net_prog, creo que no entiendes el punto de Brannon. Un hilo de un grupo de subprocesos está hecho para ser reutilizado. La próxima vez que desee reutilizar un hilo, deberá asegurarse de tener la prioridad adecuada. El comportamiento predeterminado es tener hilo en prioridad normal. Si utiliza una lib de terceros que usa el grupo de subprocesos, puede tener problemas si la prioridad no es la esperada. –

41

Como otros tienen mencionado, necesita especificar un planificador personalizado para ir con su tarea. Lamentablemente, no existe un planificador integrado adecuado.

Puede optar por las Extras de ParallelExtensions a las que se vinculó Glenn, pero si desea algo simple que pueda pegarse directamente en su código, intente lo siguiente. Utilice la siguiente manera:

Task.Factory.StartNew(() => { 
    // everything here will be executed in a thread whose priority is BelowNormal 
}, null, TaskCreationOptions.None, PriorityScheduler.BelowNormal); 

El código:

public class PriorityScheduler : TaskScheduler 
{ 
    public static PriorityScheduler AboveNormal = new PriorityScheduler(ThreadPriority.AboveNormal); 
    public static PriorityScheduler BelowNormal = new PriorityScheduler(ThreadPriority.BelowNormal); 
    public static PriorityScheduler Lowest = new PriorityScheduler(ThreadPriority.Lowest); 

    private BlockingCollection<Task> _tasks = new BlockingCollection<Task>(); 
    private Thread[] _threads; 
    private ThreadPriority _priority; 
    private readonly int _maximumConcurrencyLevel = Math.Max(1, Environment.ProcessorCount); 

    public PriorityScheduler(ThreadPriority priority) 
    { 
     _priority = priority; 
    } 

    public override int MaximumConcurrencyLevel 
    { 
     get { return _maximumConcurrencyLevel; } 
    } 

    protected override IEnumerable<Task> GetScheduledTasks() 
    { 
     return _tasks; 
    } 

    protected override void QueueTask(Task task) 
    { 
     _tasks.Add(task); 

     if (_threads == null) 
     { 
      _threads = new Thread[_maximumConcurrencyLevel]; 
      for (int i = 0; i < _threads.Length; i++) 
      { 
       int local = i; 
       _threads[i] = new Thread(() => 
       { 
        foreach (Task t in _tasks.GetConsumingEnumerable()) 
         base.TryExecuteTask(t); 
       }); 
       _threads[i].Name = string.Format("PriorityScheduler: ", i); 
       _threads[i].Priority = _priority; 
       _threads[i].IsBackground = true; 
       _threads[i].Start(); 
      } 
     } 
    } 

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued) 
    { 
     return false; // we might not want to execute task that should schedule as high or low priority inline 
    } 
} 

Notas:

  • los subprocesos de trabajo son todos los subprocesos en segundo plano, por lo que las tareas importantes no deben ser programadas utilizando este programador; solo aquellos que pueden descartarse si el proceso se cierra
  • adaptado de an implementation by Bnaya Eshet
  • No entiendo completamente cada anulación; simplemente yendo con las opciones de Bnaya para MaximumConcurrencyLevel, GetScheduledTasks y TryExecuteTaskInline.
+5

Parece que ahora tiene un lugar (no acreditado) en GitHub, con la licencia modificada (probablemente no legal) y algunas adiciones para hacer frente a la finalización/eliminación, aunque tal vez no sea el dominio de la aplicación en sí (IRegisteredObject). –

+1

Qué maravillosamente detallado si solo quiere hacer uso de la facilidad de TaskParallelLibrary Y establecer una prioridad ... Sin embargo, sin ofender. Gracias por la respuesta. –

Cuestiones relacionadas