2011-08-23 13 views
8

Estoy desarrollando una aplicación de formularios para Windows (C#), y mientras el programa se está ejecutando, crea objetos y los agrega a una lista. Tengo que procesar los elementos en la lista, con FIFO (primero en entrar primero en salir). Quiero hacer esto en un hilo de antecedentes y tengo que procesarlos en orden, número 1, número 2, número 3, etc. Y tan pronto como se agrega un elemento a la lista, quiero procesarlo. Entonces tengo que tener algo para verificar esa lista.BlockingCollection o Queue <T> para trabajos?

¿Cuál es la mejor manera de lograr esto?

Sé que blockingcollection hace algo similar, que espera que se agregue un elemento antes de procesarlo.

Puedo usar un solo hilo con la cola y solo mientras (verdadero) y tomar elementos si hay alguno?

¿Qué opinas?

Respuesta

14

Suena como debería ir para el BlockingCollection<T> si está planeando usar un hilo de fondo. Fácilmente puede hacer la misma lógica while(true) que está buscando.

El BlockingCollection<T> le da dos características importantes

  1. Es seguro para subprocesos

  2. Cuando se llama a Take(), bloqueará (es decir, esperar hasta que algo está en la cola) para usted, por lo que no tiene que escribir ningún código con ManualResetEvents y similares, lo cual es una buena simplificación.

+0

Sí exactamente! Solo estoy pidiendo esto para confirmar mi pensamiento y si alguien tiene una mejor idea :) – syncis

+2

@Jonathan Beerhalter: O, en lugar de llamar a 'Take', podría hacer que su hilo de fondo haga un' foreach' en ['GetConsumingEnumerable'' (http://msdn.microsoft.com/en-us/library/dd287186.aspx), que producirá los elementos tal como se encuentran en 'BlockingCollection '. – casperOne

+0

@syncis: 'GetConsumingEnumerable' se bloqueará hasta que se agregue un elemento al' BlockingCollection 'al igual que' Take'; la cosa es, ¿qué más está haciendo tu hilo de fondo aparte de procesar estos elementos? Si está tratando de guardar hilos; no, básicamente estás volviendo a escribir el grupo de subprocesos y esa no es una buena idea en general. Tenga en cuenta que pueden aparecer más elementos para 'Tomar' o entregados a través de 'GetConsumingEnumerable' mientras procesa sus artículos uno por uno (o puede enviarlos para procesarlos en otros hilos, según sus necesidades). – casperOne

0

SI desea bloquear si la cola está vacía, entonces utilizar BlockingCollection - es ideal ... SI usted quiere que sea más parecida a una cola (decidir cómo tratar a sí mismo con una vacía) ConcurrentQueue.

Ambos son seguros para subprocesos, en ConcurrentQueue mayoría de las operaciones se implementan de modo muy rápido ... de cualquier manera lo utilizan directamente o como el tipo de base para su BlockingCollection por ejemplo BlockingCollection<string> = new BlockingCollection<string> (new ConcurrentQueue<string>) sin bloqueo - incluso se puede poner un máximo de capactiy ese (segundo param opcional del constructor).

Cuestiones relacionadas