2012-07-13 16 views
12

Ich hatte angenommen, dass beim Beenden des Debuggens (z. B. durch Drücken der Schaltfläche Stopp oder Drücken von Umschalttaste + F5) jede Klasse, die einen Finalizer oder IDisposable implementiert, verwerfen würde.Code ausführen, wenn der VisualStudio-Debugger beendet wird

Ich habe einige Klassen, die IDisposable implementieren. Es gibt ein paar Dinge, die ich gerne (probiere) und tun würde, wenn die Anwendung den Debugger verlässt (oder in der Produktion abstürzt). Momentan scheint Dispose() nicht aufgerufen zu werden, noch ein Finalizer. ~MyClass(){}

Gibt es eine Möglichkeit, dies zu tun?

+0

Wenn der Absturz nicht durch eine abfangbare Ausnahme verursacht wird, gibt es keine Garantie für Code, der nach einem Absturz ausgeführt wird. Das ist die Natur eines Anwendungsabsturzes. Etwas ist schiefgelaufen und jetzt wurde Ihr Prozess zwangsweise beendet. –

+1

@Boo Verstanden. Aber wenn ich den Code unter mindestens einer Teilmenge der Szenarien ausführen kann, nehme ich das. – CoolUserName

+0

Das Klicken auf die Stoppschaltfläche im Debugger entspricht dem Beenden der App durch das Betriebssystem.Es ist unzeremoniell und verdammt plötzlich, ohne Rücksicht darauf, was die aktuelle Anwendung gerade tun oder tun wird. –

Antwort

2

Zum normalen Stoppen von Windows-Diensten sollten Sie Ihren Code in Ihre Stop-Methode einfügen.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.stop.aspx

Im Allgemeinen unhöflich Faden bricht und unhöflich Anwendungsdomäne entlädt nicht ‚normal‘ Finalizers gehen zu laufen - Sie weitere Details in diesem MSDN-Artikel bekommen.

https://web-beta.archive.org/web/20150423173148/https://msdn.microsoft.com/en-us/magazine/cc163716.aspx

diesen Punkt bis zu habe ich einfach über Thread gesprochen bricht als Folge der Common Language Runtime Threadabort an einem Faden zu werfen. In der Regel wird dadurch der Thread beendet. Ein Thread kann jedoch einen Thread abbrechen, sodass er den Thread nicht beendet. Um dies zu berücksichtigen, bietet die Laufzeitumgebung eine leistungsfähigere Aktion, die mit dem passenden Namen rohe Thread abbricht. Ein rauer Thread-Abbruch bewirkt, dass ein Thread die Ausführung beendet. In diesem Fall gibt die CLR keine Garantie dafür, dass ein Back-Out-Code im Thread ausgeführt wird (es sei denn, der Code wird in einem CER ausgeführt). Unhöflich, in der Tat.

Während eine typische Anwendungsdomänenentladung alle Threads in der Domäne ordnungsgemäß abbricht, werden durch ein unhandelndes Löschen der Anwendungsdomäne alle Threads in der Domäne grob abgebrochen und es wird nicht garantiert, dass mit Objekten in dieser Domäne verknüpfte normale Finalizer ausgeführt werden . SQL Server 2005 ist ein CLR-Host, der im Rahmen seiner Eskalationsrichtlinie den Abbruch unhöflicher Threads und das Entfernen unzulässiger Anwendungsdomänen verwendet. Wenn eine asynchrone Ausnahme auftritt, wird der Fehler bei der Ressourcenzuweisung auf einen Threadabbruch aktualisiert. Und wenn ein Thread-Abbruch auftritt, wird er, wenn er nicht innerhalb einer von SQL Server festgelegten Zeitspanne beendet wird, auf einen rüden Thread-Abbruch aktualisiert. Wenn ein Anwendungsdomäne-Entladevorgang nicht innerhalb einer von SQL Server festgelegten Zeitspanne abgeschlossen wird, wird ein Upgrade auf eine unautorisierte Anwendungsdomänenentladung durchgeführt. (Beachten Sie, dass die gerade ausgearbeiteten Richtlinien nicht genau das sind, was SQL Server verwendet, da SQL Server auch berücksichtigt, ob Code in kritischen Regionen ausgeführt wird, aber mehr zu diesem Thema in Kürze).

1

Nun, die CLR gibt keine Zusagen, wann Ihre Objekte gesammelt oder entsorgt werden.

Sie können versuchen, den Garbage Collector explizit aufzurufen, aber ich denke nicht, dass dies ein empfohlener Ansatz ist.

Am besten verwenden Sie Ihre IDisposable Objekte in einem using Block.
Das ist das einzige Mal, wenn Sie garantiert sind, wenn sie entsorgt werden.

+2

FWIW, 'using' ist nur Syntax Zucker für einen Versuch/schließlich, so ist es nicht mehr garantiert als ein regulärer finally Block. –

+0

Ja, es ist syntaktischer Zucker für try/finally (Dispose()). Siehe hier- "Die using-Anweisung stellt sicher, dass Dispose aufgerufen wird, selbst wenn eine Ausnahme auftritt, während Sie Methoden für das Objekt aufrufen. Sie können dasselbe Ergebnis erzielen, indem Sie das Objekt in einen try-Block setzen und dann Dispose in einem finally-Block aufrufen." http://msdn.microsoft.com/en-us/library/yh598w02%28v=vs.100%29.aspx –