Frage

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 Sequenz, die ich angenommen habe

  1. Start des statischen Konstruktors
  2. Ende des statischen Konstruktors
  3. Start von main
  4. Start von MyMethod
  5. Ende der Hauptleitung

    Nun, in jedem Szenario, wenn 4 vor 2 startet, bin ich geschraubt.Ist es möglich?

War es hilfreich?

Lösung

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.

Hier ist die Sequenz, die ich angenommen habe

  1. Start des Klassenkonstruktors (auch als cctor bezeichnet)
  2. Ende des Cctor
  3. Start von Main
  4. Start von MyMethod

    Ist das richtig?

    Nein. Die richtige Reihenfolge lautet:

    1. Start von cctor for Program, falls vorhanden. Es gibt keine.
    2. Ende des Programms für das Programm, falls vorhanden. Es gibt keine.
    3. Start von Main
    4. Start von cctor für MyClass
    5. Ende von cctor für MyClass
    6. Start von MyClass.MyMethod

      Was ist, wenn ein statischer Feldinitialisierer vorhanden ist?

      Die CLR kann in einigen Fällen die Reihenfolge ändern, in der statische Feldinitialisierer ausgeführt werden. Weitere Informationen finden Sie auf Jons Seite zu diesem Thema:

      Die Unterschiede zwischen statischen Konstruktoren und Typinitialisierern

      Ist es jemals möglich, eine statische Methode wie MyMethod aufzurufen, bevor der Cctor dieser Klasse abgeschlossen ist?

      Ja. Wenn der Cctor selbst MyMethod aufruft, wird MyMethod offensichtlich aufgerufen, bevor der Cctor abgeschlossen ist.

      Der Cctor ruft MyMethod nicht auf. Ist es jemals möglich, eine statische Methode wie MyMethod aufzurufen, bevor der Cctor von MyClass abgeschlossen ist?

      Ja. Wenn der Cctor einen anderen Typ verwendet, dessen Cctor MyMethod aufruft, wird MyMethod aufgerufen, bevor der MyClass-Cctor abgeschlossen ist.

      Kein Arzt ruft MyMethod direkt oder indirekt auf! Ist es jemals möglich, eine statische Methode wie MyMethod aufzurufen, bevor der Cctor von MyClass abgeschlossen ist?

      Nein.

      Stimmt das auch dann noch, wenn mehrere Threads beteiligt sind?

      Ja. Der Cctor wird in einem Thread beendet, bevor die statische Methode in einem Thread aufgerufen werden kann.

      Kann der Cctor mehrmals aufgerufen werden? Angenommen, zwei Threads bewirken, dass der Cctor ausgeführt wird.

      Der Cctor wird garantiert höchstens einmal aufgerufen, egal wie viele Threads beteiligt sind. Wenn zwei Threads MyMethod "gleichzeitig" aufrufen, rasen sie. Einer von ihnen verliert das Rennen und blockt, bis der MyClass-Cctor den Sieger-Thread abgeschlossen hat.

      Der verlierende Thread blockiert , bis der Cctor fertig ist? Wirklich ?

      Wirklich.

      Was ist, wenn der Cctor im gewinnenden -Thread Code aufruft, der eine Sperre blockiert, die zuvor vom verlierenden -Thread übernommen wurde?

      Dann haben Sie eine klassische Umkehrbedingung für die Sperrreihenfolge. Ihr Programm blockiert. Für immer.

      Das scheint gefährlich. Wie kann ich den Deadlock vermeiden?

      Wenn es weh tut, wenn Sie das tun, dann hört auf, das zu tun . Tun Sie niemals etwas, das einen Cctor blockieren kann.

      Ist es eine gute Idee, sich auf die Semantik der Cctor-Initialisierung zu verlassen, um komplexe Sicherheitsanforderungen durchzusetzen? Und ist es eine gute Idee, einen Cctor zu haben, der Benutzerinteraktionen durchführt?

      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.

Andere Tipps

Laut MSDN , ein statischer Konstruktor:

Ein statischer Konstruktor wird automatisch aufgerufen, um die Klasse zu initialisieren bevor die erste Instanz erstellt wird oder statische Elemente vorhanden sind referenziert.

Der statische Konstruktor wird also aufgerufen, bevor die generische Methode MyClass.MyMethod() aufgerufen wird (vorausgesetzt, nicht auch wird natürlich während der statischen Konstruktion oder der Initialisierung des statischen Felds aufgerufen).

Wenn Sie in diesem static constructor etwas Asynchrones tun, ist es Ihre Aufgabe, dies zu synchronisieren.

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 MyMethod nicht direkt oder indirekt von Ihrem statischen Konstruktor aus aufrufen, sollte dies in Ordnung sein.

Aus der Dokumentation (Hervorhebung von mir):

Ein statischer Konstruktor wird automatisch aufgerufen, um die Klasse zu initialisieren bevor die erste Instanz erstellt wird oder statische Elemente referenziert .

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.

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 Dinge in einem statischen Konstruktor machen.

Die CLR garantiert, dass der statische Konstruktor ausgeführt wird, bevor auf statische Mitglieder zugegriffen wird.Ihr Design stinkt jedoch etwas.Es wäre einfacher, so etwas zu tun:

static void Main(string[] args) 
{ 
     bool userIsAuthenticated = MyClass.AuthenticateUser();
     if (userIsAuthenticated)
         MyClass.MyMethod(); 
 } 

Wenn bei Ihrem Entwurf die Authentifizierung fehlschlägt, können Sie MyMethod nur durch Auslösen einer Ausnahme verhindern.

Es wird sichergestellt, dass der Konstruktor einer statischen Klasse aufgerufen wurde, bevor eine ihrer Methoden ausgeführt wird.Beispiel:

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!");
    }
}

Ausgabe:

Drücken Sie die Eingabetaste

// nach Drücken der Eingabetaste

Hallo eingehende ...

Hallo!

Hallo!

Hier ist die tatsächliche Reihenfolge, in der die Dinge ablaufen:

  1. Start des Main
  2. Start des statischen MyClass-Konstruktors
  3. Ende des statischen MyClass-Konstruktors
  4. Start des MyMethod
  5. Ende des Main

Oder Sie können im Debugger durchgehen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top