2012-10-10 86 views
8

Me pregunto cuál es el mejor enfoque para cargar datos de una manera segura para hilos. Tradicionalmente, he usado el patrón de doble bloqueo y eso sirvió para el propósito bastante bien. Ahora, con la adición del tipo System.Lazy, me pregunto si confiar en los aspectos internos de Lazy and Loading es mejor y hacer el trabajo de una manera mucho mejor. Se ve más limpio y fácil de leer, pero ¿es mejor?C# Threading & Blocking

¿Alguna idea?

namespace SomeNameSpace 
{ 
    public class DataStoreContext 
    { 
    private readonly static Lazy<DataStoreContext> context = new Lazy<DataStoreContext>(() => new DataStoreContext()); 
    private Lazy<Dictionary<string, Entity>> _entities = new Lazy<Dictionary<string, Entity>>(() => { return DataStoreContext.Instance.Load(); }); 
    private readonly object _syncRoot = new object(); 
    private DataStoreContext() 
    { 
    } 

    public Dictionary<string, Entity> Data 
    { 
     get { return _entities.Value; } 
    } 

    public static DataStoreContext Instance 
    { 
     get { return context.Value; } 
    } 

    private Dictionary<string, Entity> Load() 
    { 
     // Load Data from some data store. 
     return null; 
    } 

    private Dictionary<string, Entity> LoadWithLock() 
    { 
     if (_entities == null) 
     { 
     lock (_syncRoot) 
     { 
      if (_entities == null) 
      { 
      Dictionary<string, Entity> entities = this.Load(); 
      _entities = entities; 
      return _entities; 
      } 
     } 
     } 

     return _entities ; 
    } 

    public void Clear() 
    { 

    _entities = new Lazy<Dictionary<string, Entity>>(() => { return DataStoreContext.Instance.Load(); }); 

    } 
    } 
} 

Respuesta

3

por la documentación de MSDN:

Por defecto, todos los miembros públicos y protegidos de la clase perezoso es seguro para subprocesos y se pueden utilizar simultáneamente desde varios subprocesos. Estas garantías de seguridad de subprocesos se pueden eliminar opcionalmente y por instancia, usando parámetros para los constructores del tipo.

Es bastante seguro para las operaciones de lectura y escritura. Por lo tanto, me gustaría seguir con esto porque es mucho más limpio.

Pero, tal como lo indica la documentación, puede desactivar ese hilo de seguridad con algunos parámetros opcionales para el constructor.

+0

He encontrado que habría introducido un error si no hubiera cargado correctamente las entidades al invocar Clear() de inmediato. Cuanto más lo miro, más me gusta. Voy a comenzar a utilizar System.Lazy más. Gracias por su aportación. – Sam

+0

@Sam, me alegra que pueda ser de ayuda. –

8

Parece más limpio y fácil de leer, pero ¿es mejor?

Sí. El doble bloqueo es difícil de corregir. Requiere una barrera de memoria para ser correcta. Su implementación no está realmente garantizada por CIL *.

Para obtener más información, consulte this Wikipedia entry.

Al usar Lazy<T>, obtiene un código que no solo es más limpio, sino que es correcto en todas las plataformas.

* Tenga en cuenta que esto probablemente funciona perfectamente en x86 y x64, ejecutando el tiempo de ejecución de Microsoft, debido al modelo de memoria de la plataforma. Sin embargo, la especificación no garantiza que sea correcta sin las barreras de memoria adecuadas.

+0

Lo tengo. ¡Gracias! – Sam