2010-12-03 3 views
1

Sollte ich immer diese Praxis verwenden ...Verwenden von Anweisung ODER Funktion beenden, um eine Ressource zu löschen/zu löschen?

Public Function DoWork() 

    Using dc as New myDataContext() 

     ... 

    End Using 

End Function 

oder verlässt gerade die Funktion gut genug, und das gleiche tun?

Public Function DoWork() 

    Dim dc as New myDataContext() 

    ... 

End Function 

Hat das Beenden der End-Funktion dasselbe wie das Ende der Verwendung der DataContext-Ressource?

+3

Ich habe nie in .NET programmiert, aber ich kenne die Antwort, weil das Thema dreimal pro Woche kommt. Kennt der durchschnittliche .NET-Programmierer etwas über seine Sprache? – delnan

Antwort

4

Sie sind völlig anders.

Wenn das Objekt IDisposable implementiert, sollten Sie immer darauf abzielen, es zu entsorgen - der einfachste Weg ist, es in einen using Block zu wickeln.

(Und wenn das Objekt nicht IDisposable nicht implementiert, dann können Sie es nicht entsorgen oder using sowieso verwenden, auch wenn man es wollte.)

+0

Wie würden Sie mit einem Szenario umgehen, wenn Sie sich in einem Funktion-Block innerhalb einer Funktion befinden und Sie die Exit-Funktion innerhalb einer For/Next-Schleife oder etwas aufrufen müssen? – EdenMachine

+3

Der 'using' Block wird diese Situation für Sie behandeln. Es bedeutet im Grunde genommen ein "Versuch ... endlich", bei dem der 'Endlich'-Block dafür sorgt, dass 'Dispose' auf Ihrem Objekt aufgerufen wird. – LukeH

+0

@EdenMachine Warum sollte das ein Problem sein? Das Objekt wird entfernt, wenn Sie den Gültigkeitsbereich der Anweisung 'using' verlassen, auch wenn Sie von der Funktion zurückkehren oder eine Ausnahme auslösen. Es wird nur im Falle eines katastrophalen Fehlers nicht ausgeführt (OutOfMemory, ...) – CodesInChaos

4

Der Zweck der using Aussage ist Dispose auf ein Objekt aufzurufen das implementiert IDisposable. Der manuelle Weg, dies zu tun ist eine try...finally Aussage, aber das ist viel hässlicher.

Beim Verlassen der Funktion wird Dispose nicht aufgerufen. Die lokale Variable verlässt den Gültigkeitsbereich und verweist nicht mehr auf das Objekt. Dass ein Objekt keine Referenzen mehr hat, verursacht keine sofortige Reaktion. Es bedeutet nur, dass der GC von nun an sammeln kann.

So werden die nativen Ressourcen verweilen, bis der GC sie sammelt, möglicherweise viel später. Oder wenn es andere Verweise auf dieses Objekt gibt, die innerhalb von Dispose entfernt worden wären, würde es möglicherweise gar nicht erfasst.

Using statement in the VB.net specification

Und in C# (VB.net sehr ähnlich sein sollte) using auf einem Referenztyp entspricht:

{ 
    ResourceType resource = expression; 
    try { 
     statement; 
    } 
    finally { 
     if (resource != null) ((IDisposable)resource).Dispose(); 
    } 
} 

Wie Sie die finally kümmert telefonieren sehen, egal entsorgen, was passiert, in statement. Schließlich wird ausgeführt, auch wenn Sie die Funktion beenden oder eine Ausnahme auslösen.
Nur ein paar katastrophale Fehler wie OutOfMemory, StackOverflow und erzwungene Entladen der App-Domäne wird es nicht ausführen.

+0

Und dies kann zu Zeitüberschreitungen des Arbeitsspeichers oder Verbindungspools führen. – Steven

Verwandte Themen