我的Lazy<>中的InvalidOperationException价值工厂

时间:2011-06-09 23:19:42

标签: c# .net-4.0 lazy-evaluation

我的课程包含以下内容:

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

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

在访问ConfigSource属性时,我遇到了InvalidOperationException

  

ValueFactory尝试访问此实例的Value属性。

我在访问Value属性的“value factory”方法中看不到任何内容。还有什么可以触发这个例外吗?此问题只是间歇性地发生,但一旦发生,它需要重置IIS以清除异常(一旦发生就会缓存)。

6 个答案:

答案 0 :(得分:34)

事实证明,只有在尝试检查Visual Studio调试器中Value的{​​{1}}属性时才会出现此错误。这样做似乎会造成死锁,因为Lazy<>的访问似乎长时间挂起了线程,直到Value最终发生。我永远无法拦截原始InvalidOperationException,所以我无法看到内部堆栈跟踪。

我只是将此作为Visual Studio中的错误或Exception的实现。

答案 1 :(得分:12)

  

ValueFactory尝试访问此实例的Value属性。

它可以帮助某人,我能够通过检查我的整个ValueFactory过程来修复该错误。 在我的示例中,我创建了一个简单的模型,并将其与其他一些数据相关联,但在链接过程中,我在单例中访问了Value属性,导致了错误。

所以访问ValueFactory中的Lazy对象的值会抛出,例如错误。 由于错误消息已经指示; - )

答案 2 :(得分:9)

这也发生在循环依赖关系中,所以如果这些步骤无处可去,请尝试仔细检查堆栈跟踪并验证没有循环依赖关系。

答案 3 :(得分:8)

The behavior of Lazy<T> is to cache exceptions thrown by the ValueFactory。由于InvalidOperationException消息中提供的信息很少,这可能导致可能混淆的行为。 Microsoft was made aware of this issue through Connect但是,它被标记为 Wont Fix ,因为他们觉得异常本身有足够的信息来诊断问题。

如果您收到的IOE存在内部异常,则应该(不会说它会)包含足够的信息以继续。另一种可能性是你有一个try...catch块重新抛出异常(throw ex;而不是throw;),你将丢失有价值的信息。

答案 4 :(得分:6)

要确保您的异常未被缓存,请使用LazyThreadSafetyMode.PublicationOnly作为第二个参数,而不是true。

使用true,您最终会得到一个LazyThreadSafetyMode.ExecutionAndPublication。这将确保只有一个线程可以使用ValueFactory方法,但也可以确保缓存异常。

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

请参阅提供的链接sixlettervariables以获取更多信息。

答案 5 :(得分:0)

在延迟加载配置时,请确保不要调用需要所述配置的方法。这将重新调用配置加载程序,该加载程序将重新启动该过程,从而导致所描述的错误。

在我的情况下,我正在记录负载状态,而记录仪需要配置