2010-03-25 28 views
8

Necesito implementar diccionario concurrente porque .Net no contiene implementación concurrente para colecciones (ya que contendrá .NET4). ¿Puedo usar para ello "Power Threading Library" de Jeffrey Richter o presentar las variantes implementadas o algún consejo para implementar? Gracias ...Diccionario concurrente en C#

Respuesta

3

Puede usar Reflector para ver el código fuente de la implementación concurrente de .NET 4.0 RC y copiarlo en su propio código. De esta forma, tendrá menos problemas al migrar a .NET 4.0.

+1

A menos que utilice cualquier característica nueva que no esté disponible en dotNET 3.5. Y podría haber problemas de derechos de autor aquí. –

+0

Gracias, lo pensé. – jitm

+7

No recomendaría la ingeniería inversa de 4.0 Fx. Este es un problema solucionable/solucionado para el cual existen soluciones conocidas/probadas. Puedes usar el 4.0 Fx para inspirarte, pero de lo contrario no creo que este sea un buen consejo. –

3

Escribí un diccionario concurrente yo mismo (antes del .NET 4.0 System.Collections.Concurrent namespace); no hay mucho para eso. Básicamente, solo quiere asegurarse de que no se llamen ciertos métodos al mismo tiempo, por ejemplo, Contains y Remove o algo así.

Lo que hice fue usar una escritura ReaderWriterLock (en .NET 3.5 o superior, usted podría ir con ReaderWriterLockSlim) y llamar a AcquireReaderLock para todos "leer" las operaciones (como this[TKey], ContainsKey, etc.) y AcquireWriterLock para todos" "operaciones (como this[TKey] = value, Add, Remove, etc.). Asegúrese de ajustar cualquier llamada de este tipo en un bloque try/finally, liberando el bloqueo en el finally.

También es una buena idea modificar ligeramente el comportamiento de GetEnumerator: en lugar de enumerar sobre la colección existente, haga una copia y permita la enumeración sobre eso. De lo contrario, enfrentarás bloqueos potenciales.

4

Escribí una envoltura de subprocesos seguros para la clase de diccionario normal que usa enclavamiento para proteger el diccionario interno. El enclavamiento es de lejos el mecanismo de bloqueo más rápido disponible y proporcionará un rendimiento mucho mejor que el ReaderWriterLockSlim, el Monitor o cualquiera de los otros bloqueos disponibles.

El código se utilizó para implementar una clase Cache para Fasterflect, que es una biblioteca para acelerar la reflexión. Como tal, probamos una serie de enfoques diferentes para encontrar la solución más rápida posible. Curiosamente, las nuevas colecciones concurrentes en .NET 4 son notablemente más rápidas que mi implementación, aunque ambas son bastante rápidas en comparación con las soluciones que usan un mecanismo de bloqueo de menor rendimiento. La implementación de .NET 3.5 se encuentra dentro de una región condicional en la mitad inferior del archivo.

+1

Eché un vistazo a la página de inicio de Fasterflect y vi su ejemplo de clase Person teniendo esa instancia dentro de la clase. ¿No te abriría eso a problemas de concurrencia ya que no hay bloqueo en él? Hace poco hice una verificación de que los operadores C# ++/- no son atómicos y no vi ninguna información que contradijera mi comprensión. –

+1

La clase Person es solo una clase de muestra utilizada para mostrar cómo se puede utilizar Fasterflect. No está destinado a ser seguro para subprocesos. El código al que me refería anteriormente es la clase Cache ubicada en el proyecto principal de Fasterflect. Haga clic en el enlace Caché arriba para ir directamente al navegador fuente en CodePlex. –