Tatsächliche Verwendung von finally block

8

Ich habe meinen Freund nach dieser Frage gefragt, er sagte, dass damit das Objekt zerstört wird, das während der Ausnahmebehandlung erstellt wurde. Aber in c # GC ist es für das Zerstören solcher Arten von unbenutzten Objekten, was ist dann der eigentliche Einsatz von finally block. Erzähl mir ein Szenario, das damit zusammenhängt.

    
Jibu P C_Adoor 20.05.2010, 07:41
quelle

8 Antworten

11

Der GC löscht verwaltete Ressourcen (Objekte, die Ihre Anwendung im Speicher erstellt hat), wenn sie nicht mehr referenziert werden. Dies schließt Dinge wie Dateihandles, Netzwerkressourcen, Datenbankverbindungen usw. nicht ein. Sie müssen sie selbst im Block " finally " löschen oder riskieren, dass sie sich nicht löschen (obwohl sich die meisten letztendlich lösen werden). .

ODER , häufiger:

Viele Klassen, die nicht verwaltete Ressourcen entsorgt haben, implementieren die Schnittstelle IDisposable . Das bedeutet, dass Sie den Code in einen Block einbinden können und sicherstellen, dass die nicht verwalteten Ressourcen vorhanden sind gelöscht (ruft die Methode Dispose() des Objekts auf, wenn sie den Gültigkeitsbereich verlässt).

Ein gutes Beispiel für die Verwendung des Blocks finally ist die Verwendung einer Office-Interop-Bibliothek. Angenommen, Sie öffnen Microsoft Word, führen Code aus, Code schlägt fehl ... Word wird immer geschlossen, unabhängig davon, ob ein Fehler aufgetreten ist oder nicht. Daher würde ich den Schließungscode in den finally Block setzen.

    
David Neale 20.05.2010, 07:43
quelle
13

Es handelt sich um einen Block, der garantiert ausgeführt wird, unabhängig davon, ob eine Ausnahme auftritt.

Normalerweise würden Sie es verwenden, wenn es eine Art von Ressource gibt, von der Sie sichergehen wollen, dass sie ordnungsgemäß freigegeben wird. Nichts mit Objekten zu tun, die mit during the exception handling erstellt wurden. Aber sagen Sie, Sie hätten irgendeine Verbindung zu einer Datenbank oder einem Datei-Handle.

Wenn es sich um ein verwaltetes Objekt handelt, das IDisposable implementiert, ist eine bessere Vorgehensweise normalerweise das Schlüsselwort using .

    
David M 20.05.2010 07:44
quelle
4

Der GC wird schließlich das Objekt zerstören, das stimmt. Aber der finally-Block ist nützlich, wenn Sie Ressourcen ohne Speicher haben, die am besten so schnell wie möglich freigegeben werden. Wenn Sie z. B. eine Datenbankverbindung haben, möchten Sie nicht, dass die Verbindung für eine (möglicherweise unnötige) lange Zeit geöffnet bleibt, bis der Finalizer ausgeführt wird. Sie legen sie also in einen using -Block (der nur syntaktisch für Zucker ist) a try ... finally block):

%Vor%

Dies ist syntaktischer Zucker für (grundsätzlich):

%Vor%

Nun, wenn Sie nicht finally / using hätten, würde die Verbindung eventuell entfernt werden, wenn der Finalizer des Objekts ausgeführt wird, aber weil Sie nicht wissen, was das ist passieren, es ist besser, die Verwendung des Objekts in den using -Block zu packen, um sicherzustellen, dass die Verbindung geschlossen wird, sobald sie nicht mehr benötigt wird.

    
Dean Harding 20.05.2010 07:46
quelle
1

wird schließlich verwendet, um die Ausführung bestimmter Operationen sicherzustellen, unabhängig davon, ob eine Ausnahme auftritt oder nicht.

Einer der Verwendungszwecke - wenn auch nicht sehr "elegant" - ist ein Aufruf von close () auf einer zuvor geöffneten db-Verbindung. Allgemein wird für all die Dinge verwendet, die der GC nicht aufräumt (z. B. db oder Netzwerkverbindungen).

Ссылка

    
mamoo 20.05.2010 07:45
quelle
1

finally block wird verwendet, wenn Sie ein Stück Code ausführen wollen, unabhängig davon, ob die Ausnahme aufgetreten ist oder nicht. Zum Beispiel um eine Datenbankverbindung zu schließen.

    
KhanS 20.05.2010 07:47
quelle
0

finally block ist nicht nur für die Speicherfreigabe! Denken Sie über diesen Fall nach: in einem 'Versuch' blockieren Sie - 1. Öffnen Sie eine Verbindung zu einem DB 2. Führen Sie eine Abfrage aus Schritt 2 ist mit einer Ausnahme fehlgeschlagen. In jedem Fall sollten Sie jedoch die Verbindung zur DB schließen - der richtige Ort dafür ist innerhalb eines finally-Blocks.

Dies ist nur ein Beispiel. Es gibt viele verschiedene Fälle, die den finally-Block benötigen.

    
rkellerm 20.05.2010 07:46
quelle
0

Der Garbage Collector sammelt verwaltete Ressourcen zu gegebener Zeit. Für diejenigen, die sich auch an nicht verwalteten Ressourcen wie Netzwerkressourcen, Datenbankverbindungen oder Dateihandles usw. beteiligen, unterstützen sie normalerweise die Schnittstelle IDisposable . Wenn sie korrekt ausgeführt werden, werden die Ressourcen dennoch über einen Finalisierer freigegeben. Durch Dispose() ing in einem finally -Block können Sie jedoch steuern, wenn diese Ressourcen freigegeben werden.

Wenn Sie nur ein einziges IDisposable -Objekt haben, dann ist möglicherweise ein using -Block besser geeignet, obwohl die Jury immer noch nicht in der Lage ist, wenn Sie (a) mit in den Block geworfenen Ausnahmen umgehen müssen oder (b) Habe ein paar IDisposable -Objekte, die alle zusammen benutzt werden (zB SqlConnection , SqlCommand ...)

    
Rowland Shaw 20.05.2010 07:48
quelle
0

Zusätzlich zu den anderen erwähnten Szenarien tritt ein anderes häufiges mit Sperren auf. Eine synclock Anweisung ruft Monitor.Enter auf und führt einen Codeblock aus; Dann verwendet es einen finally -Block, um Monitor.Exit aufzurufen. Wenn der Code den Block verlassen würde, ohne Monitor.Exit aufzurufen, wird jeder andere Versuch, die von der Sperre geschützte Ressource zu verwenden, für immer blockiert.

Übrigens, selbst wenn etwas Schlimmes in synclock passiert, so dass die Ressource, die von der Sperre geschützt wird, als korrupt und nicht benutzt betrachtet werden sollte, ist es nicht gut, diese Situation zu behandeln. Ein viel besserer Ansatz besteht darin, dass Code innerhalb der Synclock das Objekt explizit so ungültig macht, dass jedem anderen Code, der auf die Sperre wartet, Zugriff gewährt wird und dann eine Ausnahme ausgelöst wird, wenn er versucht, das invalidierte Objekt zu verwenden / p>     

supercat 18.12.2012 00:10
quelle