2011-06-09 14 views
35

tengo una clase que contiene algo como lo siguiente:InvalidOperationException en mi Lazy fábrica <> valor

public static class Config 
{ 
    private static Lazy<ConfigSource> _cfgSrc = new Lazy<ConfigSource>(
     () => { /* "ValueFactory" here... */ }, 
     true); 

    public static ConfigSource ConfigSource 
    { 
     get { return _cfgSrc.Value; } 
    } 
} 

En el acceso a la propiedad ConfigSource, me encontré con este InvalidOperationException:

ValueFactory ha intentado acceder a la Valorar la propiedad de esta instancia.

No veo nada en mi método de "valor de fábrica" ​​que acceda a la propiedad Value. ¿Hay algo más que pueda estar desencadenando esta excepción? Este problema solo ocurre intermitentemente, pero una vez que lo hace, se necesita reiniciar IIS para borrar la excepción (que parece estar en caché una vez que ocurre).

+2

Hay un [artículo de Connect que detalla este mismo problema] (http://connect.microsoft.com/VisualStudio/feedback/details/508115/lazy-t-invalidoperationexception- mensaje-no-explícito). Se recomienda verificar el seguimiento de la pila en la excepción. – user7116

+2

¿Se puede publicar el código en '/ *" ValueFactory "aquí ... * /', o al menos algún código que lo bloquee? El problema puede estar allí. – Alxandr

+0

¿Ejecución multiproceso por casualidad? – Gleno

Respuesta

31

Resultó que este error solo se produjo al intentar inspeccionar la propiedad Value del Lazy<> en el depurador de Visual Studio. Al hacerlo, pareció crear un punto muerto porque el acceso a Value pareció colgar el hilo durante un tiempo prolongado hasta que finalmente se produjo el InvalidOperationException. Nunca pude interceptar el Exception original, por lo que no pude ver la stacktrace interna.

Acabo de describir esto como un error en Visual Studio o su implementación de Lazy<>.

+2

+1 Estoy de acuerdo con sus pensamientos de que hay un error en la implementación de 'Lazy ' Hoy encontré este mismo problema y no hay excepciones en mi código. Para resolver mis problemas, cambié a usar una propiedad con un 'get {return _val ?? (_val = CreateVal()); } ' –

+2

Visual Studio se colgó constantemente (indefinidamente?) Cuando traté de pasar el código en una aplicación web. Al separarme del proceso, devolví este error al navegador. Al desmarcar "Habilitar la evaluación de propiedades y otras llamadas a funciones implícitas" según http://stackoverflow.com/questions/3536025/why-would-the-vs2010-debugger-hang, parece que lo ha ordenado. – mwardm

8

The behavior of Lazy<T> is to cache exceptions thrown by the ValueFactory. Esto puede conducir a un comportamiento potencialmente confuso debido a la escasez de información proporcionada en el mensaje InvalidOperationException. Microsoft was made aware of this issue through Connect, sin embargo, está marcado como Wont Fix ya que consideran que hay suficiente información en la excepción para diagnosticar el problema.

Si hay una excepción interna para la IOE que recibe, debería (no dice que sí) contener suficiente información para continuar. Otra posibilidad es que tenga un bloque try...catch que vuelva a generar excepciones (throw ex; en lugar de throw;), perderá información valiosa.

5

Para asegurarse de que su excepción no se almacena en caché, use LazyThreadSafetyMode.PublicationOnly como un segundo parámetro, en lugar de verdadero.

Usando verdadero, terminará con un LazyThreadSafetyMode.ExecutionAndPublication. Esto asegurará que solo un hilo entreteres el método ValueFactory, pero también asegura que las excepciones serán almacenadas en caché.

private static Lazy<ConfigSource> _cfgSrc = new Lazy<ConfigSource>(
     () => { /* "ValueFactory" here... */ }, 
     LazyThreadSafetyMode.PublicationOnly); 

Consulte el enlace sixlettervariables proporcionado para obtener más información.

+0

No me gusta que 'PublicationOnly' aún permita que el código de inicialización se ejecute en varios subprocesos (incluso si esos resultados adicionales se descartan), pero es bueno que las excepciones no se guarden en caché. – Jacob

+0

'PublicationOnly' también permite el acceso recursivo a la propiedad' Value' de la instancia 'Lazy ' sin lanzar una 'InvalidOperationException'. –

8

Esto también me ha sucedido con dependencias circulares, por lo que si estos pasos no lo llevan a ninguna parte, intente verificar dos veces la pila y verificar que no haya dependencias circulares.

+0

sí, definí dos propiedades Lazy en términos de cada una, y obtuve esta extraña excepción –

11

ValueFactory intentó acceder a la propiedad Value de esta instancia.

Puede ayudar a alguien, pude corregir ese error inspeccionando todo el procedimiento de ValueFactory. En mi ejemplo, estaba creando un modelo simple y lo vinculé con algunos otros datos, pero durante el proceso de vinculación estaba accediendo a la propiedad Value en un singleton y eso causó el error.

Así acceder al valor de un objeto dentro del Lazy ValueFactory tiros tales un error. Como el mensaje de error ya indica ;-)

+1

Asegúrese de que la ventana de reloj, locales o autos no esté abierta. Puede intentar acceder a Value cuando se golpea el punto de interrupción dentro de ValueFactory. – Fosna

Cuestiones relacionadas