2012-03-26 12 views
5

los que se prefiere en una aplicación multi-hilo: Dictionary con objeto de bloqueo o Concurrency DictionaryDiccionario con cerradura o Diccionario de Concurency?

Cuál es eficiente y por qué debería utilizar uno o el otro?

editar 1: Almacenar Guid como clave y bool como valor.

editar 2: más de 2 subprocesos de trabajo y un subproceso de interfaz de usuario.

+2

Dependerá mucho de la situación. –

+1

Posible duplicado de [diccionario-bloqueo-vs-concurrentdiccionario] (http://stackoverflow.com/questions/1949131/net-dictionary-locking-vs-concurrentdictionary) –

Respuesta

4

Lea atentamente acerca de ConcurrentDictionary. Tiene algunas características no evidentes.

Éstos son algunos de ellos:

  • Si dos subprocesos llaman AddOrUpdate no hay garantías acerca de cuál de los delegados de fábrica se llamará e incluso hay garantía de que si un delegado de la fábrica producirá algún elemento que este artículo será almacenado en el diccionario.
  • Enumerador obtenido por GetEnumerator llamada es no una instantánea y puede modificarse durante la enumeración (que no causa ninguna excepción).
  • Keys y Values las propiedades son instantáneas de las colecciones correspondientes y pueden no corresponderse con el estado real del diccionario.
  • etc.

Así que por favor leer sobre ConcurrentDictionary de nuevo y decidir si este comportamiento es lo que necesita.

Espero que esto ayude!

2

Cuando está implementando un diccionario con un objeto de bloqueo, su preocupación principal parece seguridad de subprocesos. Entonces parece que un Dictuario concurrente ya maneja esta preocupación. Creo que no tiene sentido reinventar la rueda.

+2

No siempre. Si la velocidad es escasa, el bloqueo manual podría ser mejor. –

+1

Dependiendo de la situación, puede estar en lo cierto, por otro lado, no hay datos de rendimiento aplicables en esta situación. Las pruebas personalizadas pueden verificar la ganancia de rendimiento (si corresponde). – daryal

+0

La velocidad sí importa. –

1

Creo que ambos proporcionarán seguridad de subprocesos, pero usar un diccionario con objeto de bloqueo limitará el número de subprocesos que pueden acceder al diccionario simultáneamente a 1. Mientras utiliza el diccionario simultáneo, puede especificar el nivel simultáneo (es decir, el número de subprocesos puede acceder al diccionario al mismo tiempo). Si el rendimiento sí importa, creo que el diccionario concurrente debería ser tu elección.

5

Yo diría que tienes las siguientes opciones.

Algunas nuevas clases Framework 4.0:

  • ConcurrentDictionary. Trabaja rápido y confiable.
  • ConcurrentBag. Es colección no ordenada de objetos, por lo que funciona más rápido, pero se adapta si no necesita solo la clasificación.
  • ConcurrentStack. Es una implementación de la estructura de datos clásica LIFO (último en entrar, primero en salir) que proporciona acceso seguro para subprocesos sin necesidad de sincronización externa
  • ConcurrentQueue. Es un hilo seguro FIFO (primero en entrar, primero en salir) colección.

Todas las novedades 4.0 clases trabajar más rápido, pero tienen algunas características mencionadas por levanovd. Comparación de rendimiento de estas clases puede encontrar here.

Algunas soluciones clásicas de versiones anteriores:

  • diccionario + Monitor. Envoltura simple a cerradura
  • Diccionario + ReaderWriterLock. Mejor que el anterior, porque tiene bloqueos de lectura y escritura. Entonces, varios hilos pueden leer, y solo uno: escribir.
  • Diccionario + ReaderWriterLockSlim. Es solo la optimización del anterior.
  • Hashtable. Desde mi experiencia, es el método más lento. Consulte el método Hashtable.Synchronized(), es una solución lista para usar de Microsoft.

Si tuviera una restricción de la utilización de la versión 3.5 Marco, me gustaría utilizar Diccionario + ReaderWriterLock o ReaderWriterLockSlim.