InvalidOperationException в моей фабрике значений Lazy <> - PullRequest
38 голосов
/ 10 июня 2011

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

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

Ответы [ 5 ]

34 голосов
/ 28 июня 2011

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

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

13 голосов
/ 18 февраля 2014

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

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

Таким образом, при доступе к объекту Value Lazy внутри ValueFactory выдает таких ошибок . Как сообщение об ошибке уже указывает; -)

10 голосов
/ 21 февраля 2013

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

8 голосов
/ 10 июня 2011

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

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

6 голосов
/ 10 ноября 2011

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

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

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

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

...