Dienstag, 8. Juni 2010

Using mal anders

Die meisten Benutzer kennen das using Schlüsselwort sicherlich zum Einbinden von Namespaces und Klassen aus Anweisungen wie:
using System;

Using kann man aber auch so verwenden, dass man darüber eine Ressource für einen Block einbindet. Der Vorteil hierbei ist, dass die Ressource direkt danach wieder aus dem Speicher gelöscht wird.
Diesen Vorgang, die Freigabe von nicht mehr benötigtem Speicherplatz, erledigt unter .Net der sogenannte Garbage Collector, welcher asynchron aufgerufen wird.
Die Speicherverwaltung in .Net ist eigentlich super, doch über die hier beschriebene Methode wird der Speicher eben noch schneller freigegeben. Übrigens gilt dieses Prinzip nicht nur bei der reinen Speicherverwaltung, auch bei anderen Ressourcen, z.B. Dateizugriffen etc. ist eine schnelle Freigabe erwünscht.
Im folgenden Beispiel wird mit using eine Instanz einer Klasse benutzt. Ressourcen müssen, damit sie mit using angesprochen werden können, die Schnittstelle IDisposable implementieren.
Streamreader etc. machen das von Haus schon, nur bei selber geschriebenen Klassen muss man diese Schnittstelle manuell implementieren. Die Implementation der Methode IDisposable.Dispose() ist dabei erforderlich. Genannte Methode wird beim "Zerstören" einer Klasseninstanz aufgerufen:

     public partial class Form1 : Form
    {
         public Form1()
        {
            InitializeComponent();
        }

         private void Form1_Load( object sender, EventArgs e)
        {
             using (UsingTest InstanceUsingTest = new UsingTest())
            {   // in diesem Using - Block wird InstanceUsingTest genutzt
                InstanceUsingTest.ExampleFunction();
            }
            // außerhalb des Blocks wird der Speicher sofort freigegeben
        }

         public class UsingTest : IDisposable
        {  
            // diese Methode muss bei Implementierung von IDisposable vorhanden sein
             void IDisposable.Dispose()
            {
                MessageBox.Show("Instanz gelöscht, Speicher wieder freigegeben.");
            }

             public void ExampleFunction()
            {
                MessageBox.Show("Klasse in Benutzung.");
            }
        }
    }

1 Kommentar:

  1. Die using-Anweisung macht _nichts_ anderes, als die IDisposable.Dispose-Methode aufzurufen - und zwar in jedem Fall, wenn der Block verlassen wird.

    Was die jeweilige Instanz aus dem Dispose-Aufruf macht, ist ihre Sache. Die Instanz wird auch nicht sofort "zerstört". Durch Verlassen des using-Blocks ist auch der Scope der Instanz weg und der GC _könnte_ sie wegräumen, aber dass er es sofort macht, ist unwahrscheinlich.

    Gruß,
    Daniel

    BTW: Der GC läuft erst ab der .NET 4.0-Runtime teilweise asynchron.

    AntwortenLöschen