namespace MyNameSpace
{
static class MyClass
{
static MyClass()
{
//Authentication process.. User needs to enter password
}
public static void MyMethod()
{
//Depends on successful completion of constructor
}
}
class Program
{
static void Main(string[] args)
{
MyClass.MyMethod();
}
}
}
Вот последовательность, которую я предположил
- Запуск статического конструктора
- Конец статического конструктора
- Начало основного
- Запуск MyMethod
- Конец основного
Теперь при любом сценарии, если 4 начнутся раньше 2, я облажался. Является ли это возможным?
c#
c#-4.0
static-constructor
om471987
источник
источник
Ответы:
Вы задали здесь только один вопрос, но есть около дюжины вопросов, которые вам следовало бы задать, так что я отвечу на них все.
cctor
)Нет. Правильная последовательность:
В некоторых случаях CLR разрешено изменять порядок, в котором запускаются инициализаторы статических полей. Подробности см. На странице Джона по этой теме:
Различия между статическими конструкторами и инициализаторами типов
Да. Если сам cctor вызывает MyMethod, то очевидно, что MyMethod будет вызываться до завершения cctor.
Да. Если cctor использует другой тип, cctor которого вызывает MyMethod, то MyMethod будет вызываться до завершения cctor MyClass.
Нет.
Да. Cctor завершит работу в одном потоке, прежде чем статический метод можно будет вызвать в любом потоке.
Гарантируется, что cctor будет вызван не более одного раза, независимо от того, сколько потоков задействовано. Если два потока вызывают MyMethod «одновременно», они участвуют в гонке. Один из них проигрывает гонку и блокируется до тех пор, пока MyClass cctor не завершит работу в выигрышном потоке.
В самом деле.
Тогда у вас есть классическое условие инверсии порядка блокировок. Ваша программа заходит в тупик. Навсегда.
Если это причиняет боль, прекратите это делать . Никогда не делайте того, что может заблокировать в cctor.
Тоже не хорошие идеи. Я советую вам найти другой способ гарантировать выполнение предварительных условий ваших методов, влияющих на безопасность.
источник
Согласно MSDN , статический конструктор:
Таким образом, статический конструктор будет вызываться до
MyClass.MyMethod()
вызова статического метода ( конечно, при условии, что он не вызывается также во время статического построения или инициализации статического поля).Теперь, если вы делаете что-то асинхронное в этом
static constructor
, то ваша задача - синхронизировать это.источник
№3 на самом деле №1: статическая инициализация не начинается до первого использования класса, к которому она принадлежит.
Это возможно, если
MyMethod
вызывается из статического конструктора или статического блока инициализации. Если вы не вызываетеMyMethod
прямо или косвенно из статического конструктора, все будет в порядке.источник
static
инициализацию можно вызвать перед первым использованием в зависимости от права на оптимизацию.beforefieldinit
Е. Семантика), определяется тем, имеет ли класс C # статический конструктор.Из документации (выделено мной):
источник
Вы можете гарантировать, что 4 всегда будет после 2 (если вы не создадите экземпляр своего класса из своего статического метода), однако то же самое не верно для 1 и 3.
источник
Статический конструктор будет вызываться перед выполнением mymethod. Однако, если вы ошиблись, если 4 вызывается перед 2, я предлагаю вам переосмыслить свой дизайн. В любом случае не следует делать сложные вещи в статическом конструкторе.
источник
CLR гарантирует, что статический конструктор запускается до обращения к статическим членам. Однако ваш дизайн немного пахнет. Проще было бы сделать что-то вроде этого:
static void Main(string[] args) { bool userIsAuthenticated = MyClass.AuthenticateUser(); if (userIsAuthenticated) MyClass.MyMethod(); }
В вашем дизайне, если аутентификация не удалась, единственный способ предотвратить запуск MyMethod - это выбросить исключение.
источник
Гарантируется, что конструктор статического класса был вызван до выполнения любого из его методов. Пример:
class Program { static void Main(string[] args) { Console.WriteLine("Press enter"); Console.ReadLine(); Boop.SayHi(); Boop.SayHi(); Console.ReadLine(); } } static class Boop { static Boop() { Console.WriteLine("Hi incoming ..."); } public static void SayHi() { Console.WriteLine("Hi there!"); } }
Вывод:
источник
Вот фактический порядок, в котором все происходит:
Main
MyClass
конструктораMyClass
конструктораMyMethod
Main
источник
Или вы можете пройти через отладчик.
источник