Ja, Dispose
wird angerufen. Es wird aufgerufen, sobald die Ausführung den Bereich des using
Blocks verlässt , unabhängig davon, welche Mittel zum Verlassen des Blocks erforderlich waren, sei es das Ende der Ausführung des Blocks, eine return
Anweisung oder eine Ausnahme.
Wie @Noldorin richtig hervorhebt, wird die Verwendung eines using
Blocks im Code in try
/ kompiliert finally
, Dispose
wobei im finally
Block aufgerufen wird . Zum Beispiel der folgende Code:
using(MemoryStream ms = new MemoryStream())
{
//code
return 0;
}
effektiv wird:
MemoryStream ms = new MemoryStream();
try
{
// code
return 0;
}
finally
{
ms.Dispose();
}
Da finally
die Ausführung garantiert ist, nachdem der try
Block die Ausführung beendet hat, wird unabhängig von seinem Ausführungspfad Dispose
garantiert, dass er aufgerufen wird, egal was passiert.
Weitere Informationen finden Sie in diesem MSDN-Artikel .
Nachtrag:
Nur eine kleine Einschränkung: Da Dispose
der Aufruf garantiert ist, ist es fast immer eine gute Idee, sicherzustellen, dass Dispose
bei der Implementierung niemals eine Ausnahme ausgelöst wird IDisposable
. Leider gibt es einige Klassen in der Kernbibliothek, die unter bestimmten Umständen auslösen, wenn sie Dispose
aufgerufen werden - ich sehe Sie an, WCF-Dienstreferenz / Client-Proxy! - und wenn dies passiert, kann es sehr schwierig sein, die ursprüngliche Ausnahme aufzuspüren, wenn Dispose
sie während eines Abwickelns des Ausnahmestapels aufgerufen wurde, da die ursprüngliche Ausnahme zugunsten der neuen Ausnahme verschluckt wird, die durch den Dispose
Aufruf generiert wird . Es kann unglaublich frustrierend sein. Oder ist das frustrierend verrückt? Einer der Beiden. Vielleicht beide.