Каждый ли доступ к статическому полю входит в блокировку, проверьте, статичен ли
конструктор инициализируется, а затем инициализировать его, если это не так?
Я сомневаюсь, что это будет блокировка как таковая, я думаю, что CLR просто гарантирует, что IL упорядочен как излучаемый таким образом, что это эксклюзивно, хотя, честно говоря, я не слишком уверен.
Разве это не будет очень медленно?
private static void Main(string[] args)
{
var t1 = Task.Run(
() =>
{
Console.WriteLine($"{DateTime.Now.TimeOfDay} here 1");
var val = Test.Value;
Console.WriteLine($"{DateTime.Now.TimeOfDay} here 1 complete");
return val;
});
var t2 = Task.Run(
() =>
{
Console.WriteLine($"{DateTime.Now.TimeOfDay} here 2");
var val = Test.Value;
Console.WriteLine($"{DateTime.Now.TimeOfDay} here 2 complete");
return val;
});
Task.WaitAll(t2, t2);
}
public static class Test
{
static Test()
{
Thread.Sleep(2000);
Value = 1;
}
public static int Value { get; }
}
выход
09:24:24.3817636 here 2
09:24:24.3817636 here 1
09:24:26.3866223 here 2 complete
09:24:26.3866223 here 1 complete
То, что у вас есть, это не только крайне плохо написанный код, другим потокам приходится ждать завершения этих типов махинаций. Так что да, это может быть медленно, если вы выберете это.
Технические характеристики ECMA
15.12 Статические конструкторы
Статический конструктор для закрытого класса выполняется не более одного раза в
данный домен приложения. Выполнение статического конструктора
вызвано первым из следующих событий, происходящих в пределах
домен приложения:
- Экземпляр класса создан.
- Ссылка на любой статический член класса.
...
Потому что статический конструктор выполняется ровно один раз для каждого
закрытый тип сконструированного класса, это удобное место для обеспечения соблюдения
проверки во время выполнения параметра типа, который нельзя проверить при
время компиляции через ограничения (§15.2.5).
Нет упоминания о том, как он выполняет исключительность (как и следовало ожидать), поскольку это просто деталь реализации, однако мы знаем, что это делает .
И, наконец, потому что просмотр спецификаций - бочка веселья и веселья (отдельные результаты могут отличаться), вы можете столкнуться с более странными ситуациями, такими как создание круговых зависимостей
Можно построить круговые зависимости, которые позволяют статические
поля с переменными инициализаторами должны соблюдаться по умолчанию
значение состояния.
class A
{
public static int X;
static A()
{
X = B.Y + 1;
}
}
class B
{
public static int Y = A.X + 1;
static B() { }
static void Main()
{
Console.WriteLine("X = {0}, Y = {1}", A.X, B.Y);
}
}
производит вывод
X = 1, Y = 2
Чтобы выполнить метод Main, система сначала запускает инициализатор для
B.Y, до статического конструктора класса B. Инициализатор Y вызывает А
статический конструктор, который будет запущен из-за ссылки на значение A.X.
Статический конструктор A, в свою очередь, продолжает вычислять значение
X, и при этом извлекает значение по умолчанию Y, которое равно нулю. A.x
таким образом инициализируется в 1. Процесс запуска статического поля А
инициализаторы и статический конструктор затем завершается, возвращаясь к
Расчет начального значения Y, результатом которого становится 2.