He de comenzar a trabajar con algo de código .NET 3.5 y encontró el siguiente método de extensión que se utilizan para una caché ::Para .NET 3.5, ¿cómo haría para obtener un caché o agregar caché?
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> @this, TKey key,Func<TKey,TValue> factory,bool useLocking)
{
TValue value;
if([email protected](key,out value))
{
if (useLocking)
{
lock ((@this as ICollection).SyncRoot)
{
if ([email protected](key, out value))
{
@this[key] = value = factory(key);
}
}
}
else
{
@this[key] = value = factory(key);
}
}
return value;
}
El caché en cuestión está enchavetado mediante claves de cadena, y con useLocking = true. Siempre se accede a este método (no hay datos perdidos TryGetValue
). Tampoco hay problema al utilizar la propiedad SyncRoot
porque el diccionario es privado y en ningún otro lugar se está utilizando. El doble bloqueo es peligroso porque un diccionario no admite la lectura mientras se está escribiendo. Aunque técnicamente no se ha informado ningún problema aún, ya que el producto no se ha enviado, creo que este enfoque conducirá a las condiciones de carrera.
Cambiar el
Dictionary<,>
a unHashtable
. Perderemos la seguridad de tipo, pero podremos soportar el modelo de concurrencia que buscamos (1 escritor, lectores múltiples).Elimina TryGetValue externo. De esa forma cada lectura, requiere adquirir un candado. Esto es potencialmente malo para el rendimiento, pero adquirir un bloqueo no probado debería ser bastante barato.
Ambos son bastante asquerosos. ¿Alguien tiene una mejor sugerencia? Si este fuera el código de .NET 4, simplemente lo cambiaría a ConcurrentDictionary
, pero no tengo esa opción.
Yargh! Completamente no relacionado ... pero no escribes código usando @this. Estás en un método estático; no intente hacer que se vea como un método de instancia. –
¡este no es mi código! Si fuera mi código, agregaría validación de argumentos. –