Cuando estás trayendo una propiedad del property bag no quieres bloquear todas las property bags de todas las webs, solo necesitas asegurarte de que la propiedad que con la que estás trabajando no ha cambiado desde que empezaste el bloqueo... y para eso hace falta una manera dinámica de crear bloqueos.
Empecé esta clase con un diccionario pero después de usarla un tiempo me di cuenta de que los diccionarios no son thread safe para lectura... así que lo cambié por una hash table.
public class Locks { /// <summary> /// This hashtable will provide a lock for every different key in the cache. Hashtables are threadsafe for one writer many readers scenario /// </summary> private static Hashtable LocksCollection = new Hashtable(); public static object GetLock(string Key, params object[] args) { if (args!=null) Key = string.Format(Key, args); if (!LocksCollection.ContainsKey(Key)) { lock (LocksCollection) if (!LocksCollection.ContainsKey(Key)) LocksCollection.Add(Key, new object()); } return LocksCollection[Key]; } }
Con esta nueva clase en el método para guardar web properties solo bloqueamos la property bag en la que estamos trabajando, dejando las otras webs del servidor desbloqueadas, el código queda así:
/// <summary> /// Sets a web property to a given value. This method is thread safe. /// </summary> /// <param name="Key">The Key for the web property (case insensitive)</param> /// <param name="Value">Value to set the property to</param> public static void SetWebProperty(this SPWeb Web, string Key, string Value) { Key = Key.ToLower(); lock (Locks.GetLock("WebPropertyWriteLock - {0}", Web.ID)) { if (GetWebPropertyThreadSafe(Web, Key) != Value) { Web.Properties[Key] = Value; Web.Properties.Update(); } } }
No hay comentarios:
Publicar un comentario