example c# locking static-members concurrent-collections

c# - example - ¿El subproceso ConcurrentDictionary es seguro hasta el punto de que puedo usarlo para un caché estático?



c# concurrentdictionary example (2)

Es posible que aún deba usar el bloqueo de la misma manera que podría necesitar una transacción en una base de datos. La parte "concurrente" significa que el diccionario continuará funcionando correctamente en varios subprocesos.

Incluidos en la colección concurrente están TryGetValue y TryRemove que reconocen que alguien podría eliminar primero un elemento. El bloqueo a nivel granular está integrado, pero aún debe pensar qué hacer en estas situaciones. Para el almacenamiento en caché, a menudo no importa, es decir, es una operación idempotente.

re: almacenamiento en caché. Siento que depende de lo que esté almacenando en el caché + lo que está haciendo con él. Hay costos de lanzamiento asociados con el uso de un objeto. Probablemente para la mayoría de las cosas basadas en la web, MemCache se adapta mejor como se sugiere anteriormente.

Básicamente, si quiero hacer lo siguiente:

public class SomeClass { private static ConcurrentDictionary<..., ...> Cache { get; set; } }

¿Esto me permite evitar el uso de lock todo el lugar?


Sí, es seguro para subprocesos y sí, evita el uso de bloqueos en todo el lugar (lo que sea que eso signifique). Por supuesto, eso solo le proporcionará un acceso seguro a los subprocesos a los datos almacenados en este diccionario, pero si los datos en sí no son seguros para los subprocesos, entonces necesita sincronizar el acceso a ellos. Imagine, por ejemplo, que ha almacenado en este caché una List<T> . Ahora, thread1 recupera esta lista (de una manera segura para subprocesos ya que el diccionario concurrente te lo garantiza) y luego comienza a enumerar sobre esta lista. Exactamente al mismo tiempo, thread2 recupera esta misma lista del caché (de una manera segura para subprocesos, ya que el diccionario concurrente le garantiza esto) y escribe en la lista (por ejemplo, agrega un valor). Conclusión: si no ha sincronizado el subproceso 1, se metirá en problemas.

En lo que respecta a su uso como caché, bueno, probablemente no sea una buena idea. Para el almacenamiento en caché, le recomendaría lo que ya está integrado en el marco. Clases como MemoryCache por ejemplo. La razón de esto es que lo que está integrado en el ensamblado System.Runtime.Caching es, bueno, construido explícitamente para el almacenamiento en caché => maneja cosas como la caducidad automática de los datos si comienza a tener poca memoria, devoluciones de llamada para los elementos de caducidad de la caché y incluso podría distribuir su caché en múltiples servidores utilizando cosas como memcached, AppFabric, ..., todas las cosas con las que no podría soñar con un diccionario concurrente.