2012-10-31 9 views
10

Wenn ich eine Konsolenanwendung mit Code wie haben:Aufruf Environment.Exit() Innerhalb einer Verwendung von Block-

using (DisposableObject object = new DisposableObject()) 
{ 
    if (a condition) 
    Environment.Exit(0); 

    // Do Stuff 
} 

Wird mein Objekt ordnungsgemäß entsorgt? Oder stirbt der Faden, bevor das Objekt aufgeräumt wird?

+0

Beachten Sie, dass Sie beim Herunterfahren der Anwendung selbst dann, wenn das Objekt nicht Disposed ist, Speicher nicht wirklich verlieren (da der prozessgeschützte Speicherbereich nach Abschluss des Prozesses vollständig freigegeben wird) Wenn die Entsorgung länger anhaltende Nebenwirkungen hat (z. B. die Übergabe an eine Datenbank oder etwas, das außerhalb des Prozessumfangs liegt). –

+1

@DanBryant eine nicht freigegebene Ressource wird nicht verworfen * verwalteter * Speicher. Wenn die unverwaltete Ressource nicht gemanagter Speicher ist (möglicherweise aufgrund von Interop mit einer nicht gemanagten Sprache), könnte der Speicher nicht freigegeben sein. – Servy

+0

Ich benutze es tatsächlich auf eine 'SqlConnection', aber das' using' Block ist verschachtelt innerhalb von zwei anderen (SharePoint-Objekte). Ich wollte nur sicher sein, dass die 'Dispose()' Methoden aufgerufen würden, da die SP-Objekte nicht gelöscht werden und Fehler in den Logs erzeugt werden. –

Antwort

9

Ihre Anwendung wird beendet und der gesamte verwaltete Speicher wird zu diesem Zeitpunkt freigegeben.

Der erzeugte finally Block wird nicht ausgeführt, so dass alle Dispose Methoden nicht aufgerufen werden, so dass alle nicht-verwalteten Ressourcen kann sehr gut nicht freigegeben werden.

Siehe Don't Blindly Count on a Finalizer.

+0

Wird der '// Do Stuff' Code ausgeführt? Was macht 'Environment.Exit (0);' genau? –

+0

'// Do Stuff' wird nicht ausgeführt. 'Environment.Exit (0)' beendet den Thread und gibt 0 von main zurück. –

+0

@ OlivierJacot-Descombes - '// Do Stuff' wird nicht ausgeführt. Der Aufruf beendet einfach den Prozess (gibt einen Fehlercode zurück - der übergebene "int"). – Oded

1

Ressourcen, die das Betriebssystem kennt, werden im Allgemeinen bereinigt, wenn eine Anwendung beendet wird. Ressourcen, von denen das Betriebssystem nichts weiß, werden in der Regel nicht bereinigt.

Zum Beispiel können einige Programme, die eine Datenbank verwenden und ein Sperrparadigma implementieren müssen, das sich von allen direkt vom Datenbankserver unterstützten unterscheidet, eine oder mehrere "LockedResources" -Tabellen verwenden, um zu verfolgen, welche Ressourcen gesperrt werden sollen. Code, der eine Ressource erwerben muss, sperrt die Tabelle "LockedResources", aktualisiert sie, um anzuzeigen, welche Ressourcen gesperrt werden müssen, und gibt sie dann frei; Diese Operation in der "LockedResource" -Tabelle wird im Allgemeinen sehr schnell sein (die Tabelle "LockedResource" wird nur kurz gesperrt), selbst wenn die Anwendung die reale Ressource für eine lange Zeit halten muss. Wenn die Anwendung jedoch eine Environment.Exit ausführt, während die Tabelle "LockedResources" angibt, dass sie eine Ressource besitzt, hat das Betriebssystem keine Ahnung, wie die Tabelle "LockedResources" aktualisiert werden muss, um diese Besitzrechte zu löschen.

Im Allgemeinen sollten Dinge wie Datenbankanwendungen so gestaltet sein, dass sie auch dann robust sind, wenn eine Clientanwendung unerwartet abstürzt. Zum Beispiel könnte es eine Tabelle aktiver Clients geben, wobei jeder aktive Client eine Sperre für einen Datensatz hält, der sich selbst identifiziert. Wenn ein Client, der eine Ressource verwenden möchte, bemerkt, dass die Tabelle "LockedResources" ihn an einen anderen Client ausgecheckt hat, könnte der frühere Client prüfen, ob der Eintrag des letzteren Clients in der Tabelle "aktive Clients" noch gesperrt ist. Wenn nicht, könnte er feststellen, dass der fragliche Client gestorben ist und geeignete Maßnahmen ergreifen (erkennen, dass der Client, der gestorben ist, seine Ressource möglicherweise in einem schlechten Zustand verlassen hat). Auf der anderen Seite bedeutet die Tatsache, dass die Datenbank robust sein sollte, wenn Kunden unerwartet sterben, bedeutet nicht, dass sie immer sind. Ressourcenaufgabe ist keine gute Sache, auch wenn es in der Regel überlebbar ist.

Verwandte Themen