Cómo demostrar que el patrón de bloqueo doblemente verificado con TryGetValue de Dictionary no es seguro para subprocesos

Recientemente he visto algunos proyectos de C # que usan un patrón de bloqueo de doble verificación en unDictionary. Algo como esto:

private static readonly object _lock = new object();
private static volatile IDictionary<string, object> _cache = 
    new Dictionary<string, object>();

public static object Create(string key)
{
    object val;
    if (!_cache.TryGetValue(key, out val))
    {
        lock (_lock)
        {
            if (!_cache.TryGetValue(key, out val))
            {
                val = new object(); // factory construction based on key here.
                _cache.Add(key, val);
            }
        }
    }
    return val;
}

Este código es incorrecto, ya que elDictionary puede estar "creciendo" la colección en_cache.Add() mientras_cache.TryGetValue (fuera de la cerradura) está iterando sobre la colección. Puede ser extremadamente improbable en muchas situaciones, pero aún así está mal.

¿Hay un programa simple para demostrar que este código falla?

¿Tiene sentido incorporar esto en una prueba unitaria? Y si es así, ¿cómo?

Respuestas a la pregunta(5)

Su respuesta a la pregunta