Подтвердить что ты не робот

InvalidOperationException в моем Lazy <> value factory

У меня есть класс, содержащий что-то вроде следующего:

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 factory", который обращается к свойству Value. Есть ли что-нибудь еще, что может вызвать это исключение? Эта проблема возникает только периодически, но как только это происходит, требуется сброс IIS, чтобы очистить исключение (которое, как представляется, кэшируется после его возникновения).

4b9b3361

Ответ 1

Оказалось, что эта ошибка произошла только при попытке проверить свойство Value Lazy<> в отладчике Visual Studio. Похоже, что это создало тупик, потому что доступ к Value затем, казалось, долгое время висел в потоке, пока наконец не появился InvalidOperationException. Я никогда не мог перехватить оригинальный Exception, поэтому я не мог видеть внутреннюю стекю.

Я просто помешиваю это как ошибку в Visual Studio или их реализацию Lazy<>.

Ответ 2

ValueFactory попытался получить доступ к свойству Value этого экземпляра.

Это может помочь кому-то, я смог исправить эту ошибку, проверив всю мою процедуру ValueFactory. В моем примере я создавал простую модель и связывал ее с некоторыми другими данными, но во время процесса связывания я обращался к свойству Value в одноэлементном и вызывал ошибку.

Итак доступ к значению объекта Lazy внутри ValueFactory вызывает такую ​​ ошибку. Поскольку сообщение об ошибке уже указывает, -)

Ответ 3

Это также произошло со мной с круговыми зависимостями, поэтому, если эти шаги ни к чему не приведут, попробуйте дважды проверить стек и проверить, нет ли круговых зависимостей.

Ответ 4

Поведение Lazy<T> заключается в кешировании исключений, созданных ValueFactory. Это может привести к потенциально запутанному поведению из-за скудности информации, указанной в сообщении InvalidOperationException. Microsoft узнала об этой проблеме через Connect, однако она отмечена как Wont Fix, поскольку они считают, что в самом исключении имеется достаточно информации для диагностики проблемы.

Если существует внутреннее исключение для IOE, которое вы получаете, оно должно (не сказать, что оно будет) содержать достаточную информацию для продолжения вперед. Другая возможность заключается в том, что у вас есть блоки try...catch, которые вызывают исключения (throw ex; вместо throw;), вы потеряете ценную информацию.

Ответ 5

Чтобы убедиться, что ваше исключение не кэшировано, используйте LazyThreadSafetyMode.PublicationOnly как второй параметр, а не true.

Используя true, вы получите LazyThreadSafetyMode.ExecutionAndPublication. Это гарантирует, что только один поток вводит метод ValueFactory, но также гарантирует, что исключения будут кэшироваться.

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

См. ссылку sixlettervariables для получения дополнительной информации.

Ответ 6

При ленивой загрузке конфигурации не вызывайте методы, которые нуждаются в указанной конфигурации. Это вызовет загрузчик конфигурации, который запускается поверх процесса, что приведет к описанной ошибке.

В моем случае я регистрировал loadstate, в то время как регистратор требовал настройки