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();
}
}
}
Hier ist die Reihenfolge, die ich angenommen habe
- Start des statischen Konstruktors
- Ende des statischen Konstruktors
- Start der Hauptleitung
- Start von MyMethod
- Ende der Hauptleitung
Jetzt in jedem Szenario, wenn 4 vor 2 startet, bin ich geschraubt. Ist es möglich?
c#
c#-4.0
static-constructor
om471987
quelle
quelle
Antworten:
Sie haben hier nur eine Frage gestellt, aber es gibt ungefähr ein Dutzend Fragen, die Sie hätten stellen sollen, also werde ich sie alle beantworten.
cctor
)Nein. Die richtige Reihenfolge ist:
Die CLR kann in einigen Fällen die Reihenfolge ändern, in der statische Feldinitialisierer ausgeführt werden. Siehe Jons Seite zu diesem Thema für Details:
Die Unterschiede zwischen statischen Konstruktoren und Typinitialisierern
Ja. Wenn der Cctor selbst MyMethod aufruft, wird MyMethod offensichtlich aufgerufen, bevor der Cctor abgeschlossen ist.
Ja. Wenn der Cctor einen anderen Typ verwendet, dessen Cctor MyMethod aufruft, wird MyMethod aufgerufen, bevor der MyClass-Cctor abgeschlossen ist.
Nein.
Ja. Der Cctor wird in einem Thread beendet, bevor die statische Methode in einem Thread aufgerufen werden kann.
Der Cctor wird garantiert höchstens einmal aufgerufen, egal wie viele Threads beteiligt sind. Wenn zwei Threads MyMethod "gleichzeitig" aufrufen, laufen sie. Einer von ihnen verliert das Rennen und blockt, bis der MyClass-Cctor den Sieger-Thread abgeschlossen hat.
Ja wirklich.
Dann haben Sie eine klassische Umkehrbedingung für die Sperrreihenfolge. Ihr Programm blockiert. Für immer.
Wenn es weh tut, wenn Sie das tun, dann hören Sie damit auf . Tun Sie niemals etwas, das einen Cctor blockieren kann.
Weder sind gute Ideen. Mein Rat ist, dass Sie einen anderen Weg finden sollten, um sicherzustellen, dass die sicherheitsrelevanten Voraussetzungen Ihrer Methoden erfüllt sind.
quelle
Laut MSDN ist ein statischer Konstruktor:
Der statische Konstruktor wird also aufgerufen, bevor die statische Methode
MyClass.MyMethod()
aufgerufen wird (vorausgesetzt, er wird natürlich nicht auch während der statischen Konstruktion oder der Initialisierung des statischen Feldes aufgerufen).Wenn Sie dabei etwas Asynchrones tun
static constructor
, ist es Ihre Aufgabe, dies zu synchronisieren.quelle
Die Nummer 3 ist tatsächlich die Nummer 1: Die statische Initialisierung beginnt erst bei der ersten Verwendung der Klasse, zu der sie gehört.
Es ist möglich, wenn
MyMethod
vom statischen Konstruktor oder einem statischen Initialisierungsblock aufgerufen wird. Wenn Sie nichtMyMethod
direkt oder indirekt von Ihrem statischen Konstruktor aus aufrufen , sollte es Ihnen gut gehen.quelle
static
Initialisierung tatsächlich vor der ersten Verwendung aufgerufen werden kann, abhängig von der Berechtigung zur Optimierung.beforefieldinit
Semantik) ausgelöst wird, hängt jedoch davon ab, ob die C # -Klasse über einen statischen Konstruktor verfügt.Aus der Dokumentation (Schwerpunkt Mine):
quelle
Sie können garantieren, dass 4 immer nach 2 kommt (wenn Sie keine Instanz Ihrer Klasse mit Ihrer statischen Methode erstellen), dies gilt jedoch nicht für 1 und 3.
quelle
Der statische Konstruktor wird aufgerufen, bevor mymethod ausgeführt wird. Wenn Sie jedoch geschraubt sind, wenn 4 vor 2 aufgerufen wird, empfehle ich Ihnen, Ihr Design zu überdenken. Sollte sowieso keine komplizierten Sachen in einem statischen Konstruktor machen.
quelle
Die CLR garantiert, dass der statische Konstruktor ausgeführt wird, bevor auf statische Elemente zugegriffen wird. Ihr Design stinkt jedoch etwas. Es wäre einfacher, so etwas zu tun:
Wenn bei Ihrem Entwurf die Authentifizierung fehlschlägt, können Sie MyMethod nur durch Auslösen einer Ausnahme verhindern.
quelle
Es wird sichergestellt, dass der Konstruktor einer statischen Klasse aufgerufen wurde, bevor eine ihrer Methoden ausgeführt wird. Beispiel:
Ausgabe:
quelle
Hier ist die tatsächliche Reihenfolge, in der die Dinge untergehen:
Main
MyClass
KonstruktorsMyClass
KonstruktorsMyMethod
Main
quelle
Oder Sie können im Debugger durchgehen.
quelle