2009-04-02 9 views
8

En el siguiente código:ContainsKey hilo de seguridad

public class StringCache 
{ 
    private readonly object lockobj = new object(); 

    private readonly Dictionary<int, string> cache = new Dictionary<int, string>(); 

    public string GetMemberInfo(int key) 
    { 
     if (cache.ContainsKey(key)) 
      return cache[key]; 
     lock (lockobj) 
     { 
      if (!cache.ContainsKey(key)) 
       cache[key] = GetString(key); 
     } 
     return cache[key]; 
    } 

    private static string GetString(int key) 
    { 
     return "Not Important"; 
    } 
} 

1) ¿Es seguro para hilos ContainsKey? IOW, ¿qué sucede si ese método se está ejecutando cuando otro hilo está agregando algo al diccionario? 2) Para la primera memoria caché de devolución [clave], ¿hay alguna posibilidad de que pueda devolver un valor ilegible?

TIA,

MB

Respuesta

14

El hilo de seguridad inherente de ContainsKey no importa, ya que no hay sincronización entre ContainsKey & caché [clave].

Por ejemplo:

if (cache.ContainsKey(key)) 
    // Switch to another thread, which deletes the key. 
    return cache[key]; 

MSDN es bastante claro en este punto:

Para permitir que la colección sea accesible por múltiples hilos para la lectura y la escritura, debe implementar su propio sincronización.

Para obtener más información, JaredPar publicó una gran entrada de blog en http://blogs.msdn.com/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx en colecciones seguras para subprocesos.

1

Esto es lo que dice en la estática Pública MSDN documentation:

(Shared en Visual Basic) de este tipo son seguros para subprocesos. No se garantiza que ningún miembro de instancia sea seguro para subprocesos.

Un diccionario < (De < (TKey, TValue>)>) puede soportar múltiples lectores Al mismo tiempo, siempre y cuando no se modifique la colección . Aún así, enumerando a través de una colección es intrínsecamente no es un procedimiento thread-safe. En el raro caso en que una enumeración contenga accesos de escritura , la colección debe ser bloqueada durante toda la enumeración. Para permitir el acceso a la colección por varios hilos para leer y escribir, debe implementar su propia sincronización .

Si leo correctamente, no creo que sea seguro para subprocesos.

5

No, ContainsKey no es seguro para subprocesos si está escribiendo valores mientras intenta leer.

Sí, existe la posibilidad de que pueda obtener resultados no válidos, pero es probable que comience a ver excepciones primero.

Eche un vistazo al ReaderWriterLockSlim para bloquear en situaciones como esta: está hecho para hacer este tipo de cosas.

1

El diccionario no es Thread-Safe.

Si dicen que

lo que sucede si ese método es ejecutando cuando otro hilo es añadir algo al diccionario?

entonces supongo que otras funciones también tienen acceso al cache. Necesita sincronizar accesos (lectura y escritura) al cache. Use su objeto de bloqueo en todas estas operaciones.

Cuestiones relacionadas