2010-08-03 11 views
11

Actualmente estoy lidiando con un problema donde tengo que enviar muchísimas funciones a otro hilo para evitar que la función actual se bloquee. ahora me pregunto cuál es la forma más rápida de realizar esta tarea.¿La forma más rápida de ejecutar un método de forma asíncrona?

Actualmente estoy pegado con

ThreadPool.UnsafeQueueUserWorkItem 

como ligeramente más rápido que el QueueUserWorkItem regular. sin embargo, me temo que el subproceso puede bloquear esto aquí. ¿Hay una forma más rápida de enviar una llamada a otro hilo? solo me pregunto cuál es la mejor práctica para tal tarea? código inseguro no sería un problema ya que está en un escenario donde ya se usa mucha interoperabilidad. gracias j.

+4

Cuando dicen 'más rápido' ¿Quiere decir que usted quiere reducir el bloqueo en el hilo 'principal'? Específicamente, ¿la llamada que pone en cola el elemento para el procesamiento en segundo plano regresa lo más rápido posible? –

+0

WRT su preocupación declarada, el grupo de hilos no bloquea para esa llamada (o la normal 'segura'), pero devuelve un bool para si fue puesta en cola con éxito, con la teoría de que si devuelve falso, es posible que quiero ejecutarlo en el hilo actual, o intentarlo más tarde, o lo que sea. –

+0

¿Está enviando el mismo método cada vez? ¿Necesitan operar de manera sincronizada el uno con el otro? ¿Es aceptable el enfoque productor/consumidor? (por lo que la persona que llama simplemente agrega algo a una cola). ¿Qué versión de .NET es esto? –

Respuesta

2

CLR (4) equipo recomienda:

tarea es ahora la mejor forma de cola de trabajo para el grupo de subprocesos.

Lea CLR 4.0 ThreadPool Improvements: Part 1 y New and Improved CLR 4 Thread Pool Engine para obtener información detallada. En resumen, las razones son: colas locales, reutilización de hilos, robo de trabajo. Básicamente para el objetivo de equilibrio de carga.

Extras:

No entiendo por qué no es la respuesta (downvoted).

Usted escribió

tengo que despachar el infierno una gran cantidad de funciones a otro hilo a evitar que la función actual de bloqueo"

contesto: Algunos TPL (existe para net35) 'bloques' (colecciones concurrentes, primitivas de hilado, etc.) están diseñados específicamente para un acceso altamente concurrente, con el se centran en minimizar o eliminar el bloqueo para efectos buena gestión del trabajo. Puede usar esos bloques también (por ejemplo, BlockingCollection para su problema). TPL diseñado para crear y manejar cientos (o incluso miles) de operaciones (tareas) vinculadas con CPU con una sobrecarga mínima (o millones con la ayuda de PLinq).

Se preguntó:

Me pregunto cuál es la mejor práctica es para tal tarea?

yo ya he respondido: mejores prácticas - TPL (razoné, no sólo mi recomendación)

+0

+ Extras. Por favor, agregue comentarios si downvoting – SalientBrain

1

Insertar elementos múltiples o más grandes a la vez debería reducir la sobrecarga.

editar después de leer uno de sus comentarios:

he experimentado cosas similares. Mi remedio habitual no es enviar inmediatamente todas las solicitudes asincrónicas, sino imitar lo que hace Nagle's Algorithm para TCP.

Aquí, al recibir una Solicitud() lo enviaría inmediatamente solo si no hay trabajos asíncronos pendientes. Si el trabajo asíncrono está pendiente, se enviaría solo si hubiera transcurrido un cierto número de milisegundos desde la primera Solicitud no enviada o hasta que se haya acumulado una determinada cantidad de Solicitudes pendientes().

Este es un patrón efectivo para reducir la sobrecarga al obtener solicitudes frecuentes() sobre las que no tiene control. Espero que ayude.

+0

Esto no funcionaría en contra de la premisa del OP que la intención es despachar muy rápido. La ejecución de los consumidores no le importa al productor. En tal caso, un tipo de almacenamiento en memoria intermedia de Nagle podría no ser útil, ¿no? – Gangadhar

+0

"despacho muy rápido" es ambiguo. Un algoritmo Nagle garantiza una latencia de despacho razonablemente baja y una muy buena producción. Eso es lo que llamo despacho rápido aunque escuchemos el OP. –

0

Tal vez podría incluir todas sus solicitudes de envío en una lista <> y activar otra cadena de fondo para realizar las llamadas a QueueUserWorkItem.

¿Estoy entendiendo el problema correctamente?

Cuestiones relacionadas