2016-05-05 2 views
1

Возможно, я где-то пропустил какую-то ослепительно очевидную документацию, но статическая переменная-член-переменная readonly гарантирована, чтобы быть правильно инициализированной для использования в качестве объекта блокировки?Есть ли объект блокировки C# для ленивой инициализации

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

Я видел много объявлений об объекте блокировки, подобных этому.

private static readonly object _lockObj = new object();

Может это гарантия того, что несколько потоков не будет, по несвоевременности, инициализировать два объекта одновременно и зафиксировать на двух объектах? Или я должен создать объект блокировки следующим образом.

private static readonly Lazy<object> _lockObj = new Lazy<object>(() => new object());

P.S. Я имею в виду ключевое слово C# lock(_lockObj){...} для блокировки.

+0

Блокировка может быть выполнена на любом объекте. Если бы ваше высказывание было правдой, поле «static readonly» могло иметь несколько значений, которые не были бы предназначены. Пока они обращаются к тому же классу, вам должно быть хорошо идти. Будьте осторожны с родовыми классами tho;) –

+1

CLR гарантирует, что типы будут инициализированы один раз за приложение. Инициализаторы статического поля запускаются внутри инициализатора типа перед телом статического конструктора типа (если он есть). Поэтому, предполагая, что два потока активируют метод в одном и том же приложении, нет никакой возможности, что будет гонка, где они получат разные объекты блокировки. –

+0

Если это не сработало, я не вижу, как ваше решение поможет. Вы просто переместите проблему с риском того, что у вас есть два экземпляра «Lazy», которые затем инициализируют два разных объекта. –

ответ

2

Время выполнения гарантирует только одну копию поля статического члена. Вы даже можете использовать его без каких-либо экземпляров класса. Это было бы безопасно для использования в качестве объекта блокировки.

+0

Так что, даже если объект немного сложнее, например семафор, я могу это сделать. 'public static readonly SemaphoreSlim _semaphore = new SemaphoreSlim (3)' без использования Lazy <> инициализации? – ShuberFu

+0

Да, _semaphore построен до его использования. –

+0

Я не думаю, что вам нужно использовать Lazy все время. Это не похоже на то, что ваше приложение является критическим для ресурсов. –