2011-11-17 12 views
8

Tengo una tabla de datos llena de entradas de resumen y mi software necesita acceder a un servicio web para obtener detalles, luego regréselos a la base de datos. Pasar por la tabla de forma sincrónica mientras llamas al servicio web y esperar la respuesta es demasiado lento (hay miles de entradas), así que me gustaría tomar los resultados (10 o más por vez) y enhebrarlo para que realice 10 operaciones al mismo tiempo.La mejor manera de administrar el grupo de subprocesos contra la cola de la base de datos

Mi experiencia con hilos C# está limitada, por decir lo menos, ¿cuál es el mejor enfoque? ¿.NET tiene algún tipo de sistema de cola de hilos que puedo usar para asegurarme de que los resultados se manejen de manera correcta y ordenada?

+2

¿Qué versión de .Net utiliza? Hay grandes mejoras en la programación multiproceso en .NET 4. – svick

+0

Debería haber incluido eso .. Actualmente apuntando a 3.5 pero puedo ir a 4.0 sin muchos problemas. –

Respuesta

5

Según la versión de .NET Framework tiene dos opciones bastante buenas.

Puede usar ThreadPool.QueueUserWorkItem en cualquier versión.

int pending = table.Rows.Count; 
var finished = new ManualResetEvent(false); 
foreach (DataRow row in table.Rows) 
{ 
    DataRow capture = row; // Required to close over the loop variable correctly. 
    ThreadPool.QueueUserWorkItem(
    (state) => 
    { 
     try 
     { 
     ProcessDataRow(capture); 
     } 
     finally 
     { 
     if (Interlocked.Decrement(ref pending) == 0) 
     { 
      finished.Set(); // Signal completion of all work items. 
     } 
     } 
    }, null); 
} 
finished.WaitOne(); // Wait for all work items to complete. 

Si está utilizando .NET Framework 4.0 se puede utilizar el Task Parallel Library.

var tasks = new List<Task>(); 
foreach (DataRow row in table.Rows) 
{ 
    DataRow capture = row; // Required to close over the loop variable correctly. 
    tasks.Add(
    Task.Factory.StartNew(
    () => 
     { 
     ProcessDataRow(capture);   
     })); 
} 
Task.WaitAll(tasks.ToArray()); // Wait for all work items to complete. 

Hay muchas otras formas razonables de hacerlo. Destaco los patrones anteriores porque son fáciles y funcionan bien. A falta de detalles específicos, no puedo decir con certeza si alguno de los dos será una combinación perfecta para su situación, pero deberían ser un buen punto de partida.

Actualización:

tuve un corto período de actividad cerebral insatisfactoria. Si tiene el TPL disponible, también podría usar Parallel.ForEach como un método más simple que todo lo que mencioné anteriormente en Task hocus-pocus.

Parallel.ForEach(table.Rows, 
    (DataRow row) => 
    { 
    ProcessDataRow(row); 
    }); 
+0

Por cierto, puede utilizar el TPL en 3.5 si descarga el respaldo de Extensiones reactivas del sitio web de Microsoft. –

+0

Cosas increíbles, muchas gracias a todos. ¡Parece que hay varias formas de despellejar a este gato! –

+0

Solo una cosa (¡y sé que iré a RTFM!), Pero ¿cómo funciona esta escala? Haré miles de estas filas y definitivamente no quiero iniciar miles de hilos al mismo tiempo. Estoy asumiendo (¿esperando?) existe algún tipo de límite incorporado, por lo que no detiene la computadora del usuario. –

5

¿.NET tiene algún tipo de sistema de cola de hilos que puedo usar para asegurarme de que los resultados se manejen correctamente y en orden?

Esto era algo añadido en .NET 4. La clase BlockingCollection<T>, por defecto, actúa como una cola segura hilo para escenarios productor/consumidor.

Hace que sea bastante fácil crear una serie de elementos que "consuman" de la colección y el proceso, con uno o más elementos que se suman a la colección.

+0

Muy bien, definitivamente lo verificare. ¡Gracias! –

+0

¿Qué pasa con la Cola concurrente? http://msdn.microsoft.com/en-us/library/dd267265.aspx? – Dykam

+0

@Dykam 'BlockingCollection ', de forma predeterminada, ajusta un 'ConcurrentQueue '. Si bien puede usar el CQ directamente, si desea trabajar en un escenario de productor/consumidor, como se describe, BC lo simplifica un poco. –

Cuestiones relacionadas