Вы задали здесь только один вопрос, но есть дюжина или около того вопросов, которые вы должны были задать, поэтому я отвечу на все.
Вот последовательность, которую я предполагал
- Начало конструктора класса (также известного как
cctor
)
- Конец контроля
- начало Главного
- начало MyMethod
Это правильно?
Нет. Правильная последовательность такова:
- Запуск cctor for Program, если он есть. Нет.
- Конец cctor для программы, если он есть. Нет.
- Начало основного
- Запуск cctor для MyClass
- Конец cctor для MyClass
- Начало MyClass.MyMethod
Что делать, если есть инициализатор статического поля?
В некоторых случаях среде CLR разрешено изменять порядок запуска инициализаторов статических полей. Подробнее см. на странице Джона по этому вопросу:
Различия между статическими конструкторами и инициализаторами типов
Возможно ли, чтобы статический метод, такой как MyMethod
, был вызван до завершения cctor этого класса?
да. Если cctor сам вызывает MyMethod, очевидно, что MyMethod будет вызван до завершения cctor.
CCTOR не вызывает MyMethod. Возможно ли, чтобы статический метод, такой как MyMethod
, был вызван до завершения cctor MyClass?
да. Если cctor использует другой тип, cctor которого вызывает MyMethod, то MyMethod будет вызван до завершения cctor MyClass.
Никакие контролеры не вызывают MyMethod прямо или косвенно! Теперь возможно ли, чтобы статический метод, такой как MyMethod
, вызывался до завершения cctor MyClass?
No.
Это все еще верно, даже если задействовано несколько потоков?
да. cctor завершит работу в одном потоке до того, как статический метод можно будет вызвать в любом потоке.
Можно ли вызывать cctor более одного раза? Предположим, что два потока вызывают запуск cctor.
Гарантируется, что cctor будет вызываться не более одного раза, независимо от того, сколько потоков задействовано. Если два потока вызывают MyMethod «одновременно», они соревнуются. Один из них проигрывает гонку и блокируется до тех пор, пока cctor MyClass не завершит работу в победном потоке.
Проигравший поток блокируется до тех пор, пока cctor не будет выполнен? Правда?
Действительно.
А что, если cctor в победившей нити вызовет код, блокирующий блокировку, ранее взятую проигравшей нитью?
Тогда у вас есть классическое условие инверсии порядка блокировки. Ваша программа заблокирована. Навсегда.
Это кажется опасным. Как избежать тупика?
Если вам больно, когда вы это делаете, прекратите это делать. Никогда не делайте того, что может заблокировать контроль.
Стоит ли полагаться на семантику инициализации cctor для обеспечения соблюдения сложных требований безопасности? И это хорошая идея иметь cctor, который взаимодействует с пользователем?
Ни одна из хороших идей. Мой совет заключается в том, что вам следует найти другой способ обеспечить соблюдение предварительных условий ваших методов, влияющих на безопасность.
person
Eric Lippert
schedule
22.02.2012