2011-06-22 7 views
13

Un ConcurrentBag permitirá que varios hilos agreguen y quiten elementos de la bolsa. Es posible que un hilo agregue un artículo a la bolsa y luego termine retirando ese mismo artículo. Dice que el ConcurrentBag no está ordenado, pero ¿qué tan desordenado es? En un solo hilo, la bolsa actúa como una pila. ¿Significa desordenado "no como una lista vinculada"?¿Qué es un uso del mundo real para ConcurrentBag <T>?

¿Qué es un uso del mundo real para ConcurrentBag?

+5

¿Qué quiere decir "cómo es que no ordenada"? Hay un orden definido o no lo hay. Eso es como decir "¿Qué tan muerto está Elvis?" –

+0

El pedido de los elementos almacenados no es asunto del cliente. Entonces, desde el punto de vista de API, "desordenado" siempre se refiere al orden de enumeración (del método 'GetEnumerator'). –

+3

"no ordenado" significa que no hay garantías sobre el pedido.El comportamiento de la implementación actual parece ser que actúa como una pila cuando el mismo subproceso se agrega y se elimina, y como una cola cuando un subproceso se toma de la colección de otro. Pero no contaría con ese comportamiento. Consulte http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=842 para obtener más información. 'ConcurrentBag' puede proporcionar un mejor rendimiento que' ConcurrentQueue' si el orden no es importante, y si los hilos pueden ser productores y consumidores. –

Respuesta

3

Las bolsas son realmente útiles para rastrear recuentos de instancias. Por ejemplo, si desea mantener un registro de los hosts para los que está atendiendo las solicitudes web, puede agregar su IP a la cartera cuando comience a atender la solicitud, y eliminarla cuando finalice.

El uso de una bolsa le permitirá saber de un vistazo qué direcciones IP está prestando actualmente. También le permitirá consultar rápidamente si está dando servicio a una dirección IP determinada.

Si utiliza un conjunto para esto en lugar de una bolsa, tener múltiples solicitudes concurrentes desde la misma dirección IP arruinará su mantenimiento de registros.

+7

Usted dice agrega su IP a la bolsa y luego quítela cuando termine. ¿Cómo se elimina un artículo específico de una bolsa? –

+2

@Dustin: Buena pregunta. Estaba pensando en ['ConcurrentHashMultiset'] (https://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/collect/ConcurrentHashMultiset.html) (el equivalente de Java de' ConcurrentBag') cuando estaba escribiendo mi respuesta, que _sea_ tiene un método 'eliminar'. No tengo idea de para qué sirve la clase .NET 'ConcurrentBag'. :-P –

+2

Eso está bien, basándome en su respuesta, pude idear un escenario del mundo real aplicable a mí mismo. –

1

Cualquier cosa donde solo necesite realizar un seguimiento de lo que hay y no necesita acceso aleatorio ni orden garantizada. Si tiene un hilo que agrega elementos para procesar y un hilo que elimina elementos para procesarlos, una bolsa simultánea funcionaría bien si no le importa que se procesen en orden FIFO.

+3

escenario del mundo real ... –

1

Gracias a @Chris Jester-Young, se me ocurrió un escenario bueno y real que realmente se aplica a un proyecto en el que estoy trabajando.

descubrimiento - Proceso - Tienda

Encuentra - hilos 1 & 2 se ajustan a encontrar o raspar los datos (sistema de archivos, web, etc.). Estos resultados se almacenan en ConcurrentBag1.

Proceso - hilos 3 & 4 se fijan para tomar de ConcurrentBag1, limpio/transformar/proceso de los datos y luego almacenar los resultados en ConcurrentBag2.

Tienda - hilos 5 se configura para recopilar resultados de ConcurrentBag2 y almacenar los resultados en SQL.

+0

Según la descripción, parece que sería mejor implementarlo usando colas en capas (posiblemente instancias 'ConcurrentQueue' o' BlockingCollection') en lugar de la clase 'ConcurrentBag'. Parece haber una buena cantidad de superposición entre el uso de la clase, así que puedo estar equivocado. –

12

Como no hay pedidos, el ConcurrentBag tiene una ventaja de rendimiento sobre ConcurrentStack/Queue. Es implementado por Microsoft como almacenamiento local de hilos. Entonces cada hilo que agrega elementos hace esto en su propio espacio. Al recuperar elementos provienen del almacenamiento local. Solo cuando eso está vacío, el hilo roba el elemento de otro almacenamiento de subprocesos. Entonces, en lugar de una simple lista, un ConcurrentBag es una lista distribuida de elementos. Y es casi sin bloqueo y debería escalarse mejor con alta concurrencia.

Desafortunadamente en .NET 4.0 no era un problema de rendimiento (fija en 4,5) ver http://ayende.com/blog/156097/the-high-cost-of-concurrentbag-in-net-4-0

Cuestiones relacionadas