Я хочу, чтобы некоторые из моих объектов ленивых инициализируются как:C# с помощью отложенной инициализации и замок вместе
private static Lazy<MappingEngine> engine = new Lazy<MappingEngine>(() =>
{
return new MappingEngine();
})
И я не хочу несколько потоков, чтобы получить доступ к этому объекту после его инициализации. Должен ли я использовать механизм блокировки для предотвращения этого или Lazy поддерживает безопасность потока таким образом? Использование Lazy и lock вместе не казалось правильным способом.
В docs говорится, что «Создание объекта поток Ленивого безопасен, не защищает лениво инициализирован объект. Если несколько потоков могут получить доступ к лениво инициализирован объекту, вы должны сделать его свойство и методы безопасны для многопоточного доступа.»
Является ли пользовательский тип, который является ленивым и который блокирует каждый раз engine.Value
, называется логической задачей? Приведем пример:
public class MyLazyType<T> : Lazy<T>
{
private object lockObj = new object(); //not static since the reference to this class will be
public MyLazyType(Func<T> valueFactory) : base(valueFactory)
{
}
public new T Value
{
get
{
lock (lockObj)
{
return base.Value;
}
}
}
}
Использование:
private static MyLazyType<MappingEngine> engine = new MyLazyType<MappingEngine>(() =>
{
return new MappingEngine();
})
Если мы установим блокировку при доступе к myLazy.Value (как в MyLazyType <>), не делает ли это безопасным для всех вызовов SomeNonThreadsafeMethod? – sotn
@sotn Нет, поскольку в момент, когда вызывается 'SomeNonThreadsafeMethod', мы больше не входим в область блокировки. – spender
Упс :) Не знаю, что я думал, когда писал этот класс :) На самом деле, я подумал об этом, пока я отправляю вопрос. Благодарю. – sotn