Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Empfohlene Antworten

Veröffentlicht

Hallo

ich kämpfe momentan mit der Schnittstelle IDisposable, über die ich ein Referat halten soll. Ich verstehe diese aber einfach nicht. Hab schon gegoogelt usw aber nichts gefunden, was mir weiter hilft. Um IDisposable zu erklären bräuchte ich nämlich ein Beispiel. Bis jetzt sieht das Ganze so aus:

class MyDisposableClass : IDisposable

    {

        private bool IsDisposed = false;

        public int Number;


        //Konstruktor

        public MyDisposableClass(int zahl)

        {

            Number = zahl;

        }


        //Destruktor

        ~MyDisposableClass()

        {

            Dispose(false);

        }


        //Implementierung der Schnittstelle IDisposable

        public void Dispose()

        {

            Dispose(true);

            GC.SuppressFinalize(this);

        }


        protected virtual void Dispose(bool Disposing)

        {

            if (!IsDisposed)

            {

                //Methode wird zum ersten Mal aufgerufen

                if (Disposing)

                {

                    //Managed Objekte

                }


                //Unmanaged Objekte

            }

            //Dafür sorgen, dass Methode nicht mehr aufgerufen werden kann

            IsDisposed = true;



class Program

    {


        public bool IsDisposed = false;


        static void Main(string[] args)

        {

            //Objekte werden instanziert

            MyDisposableClass Vier = new MyDisposableClass(4);

            MyDisposableClass Zehn = new MyDisposableClass(10);


            //Objekte werden ausgegeben

            Console.WriteLine(Vier.Number);

            Console.WriteLine(Zehn.Number);

            Console.ReadLine();


            //Objekt Zehn wird zerstört

            Zehn.Dispose();


            //Versuch: Objekte ausgeben

            Console.WriteLine(Vier.Number);

            Console.WriteLine(Zehn.Number);

            Console.ReadLine();


        }

    }

Was genau muss ich denn in der MyDisposableClass bei //Managed Objekte eintragen? Oder weiß jemand wo ich ein Beispiel finde, an dem ich es mir selbst abschauen kann?

Ich hoffe ihr könnt mir helfen.

LG

Tinerina

btw. ist es im Grunde nicht weiter von Belang, sich über diese Schnittstelle Gedanken zu machen, da man Sie in der Praxis -also im "Ottonormal-Code"- nicht einsetzt.

Haupteinsatzgebiet wäre die Behandlung von unmanaged Code innerhalb von managed code. Ansonsten sehe ich keinen Sinn darin.

@lilith2k3: kann ja schlecht in meinem Referat sagen: die braucht man nicht, also hab ich das Referat nicht gemacht

Hab jetzt mal ein neues Beispiel gemacht:

class DisposeSample : IDisposable

    {

        //bool zur Kontrolle ob Dispose schon durchgeführt wurde

        private bool disposed = false; 

        private StreamWriter sw;


        //Konstruktor

        public DisposeSample(string path)

            : base()

        {

            //StreamWriter sw erhält den Pfad der Datei, auf die er zugreifen soll

            sw = new StreamWriter(path);

        }


        // Schreibe in die Textdatei

        public void Write(string value)

        {

            sw.Write(value);

        }


        // Schreibe eine Zeile in die Textdatei

        public void WriteLine(string value)

        {

            sw.WriteLine(value);

        }


        // Methode Dipsose wird implementiert

        public void Dispose()

        {

            Dispose(true);

            GC.SuppressFinalize(this);

        }


        private void Dispose(bool disposing)

        {

            // Kontrolliert, ob Dispose schon einmal aufgerufen wurde

            if (!this.disposed)

            {

                // wenn nicht:

                if (disposing)

                {

                    // Freigeben verwalteter Ressourcen (managed resources)

                    sw.Dispose();

                }

                #region "Dipsose für Handles und Pointers"

                // Hier her kommt der Code rein um unverwaltete Ressourcen (unmanaged resources) freizugeben.

                // Ist "disposing" falsch, wird nur Code ausgeführt, der hier drin steht

                #endregion


                // Wenn Dispose ausgeführt wurde, wird dies mit dem bool disposed bestätigt:

                disposed = true;

            }

        }


        //Destruktor

        ~DisposeSample() 

        {

            Dispose(false);

        }

    }



class Program

    {

        static void Main(string[] args)

        {

            // erstelle das DisposeSample Objekt sample

            DisposeSample sample = new DisposeSample(@"C:\tmp\IDisposableSample.txt");


            // schreibe "Hello World!"

            System.Console.WriteLine(@"Write ""Hello World!"" Line."); // In die Konsole

            sample.WriteLine("Hello World!"); // In die Textdatei


            // Zerstöre DisposeSample Objekt sample

            System.Console.WriteLine(@"Dispose ""DisposeSample"" object.");

            sample.Dispose();


            // Warte auf Eingabe

            System.Console.ReadLine();


            // schreibe "Hello World 2!"

            System.Console.WriteLine(@"Write ""Hello World 2!"" Line."); // In die Konsole

            sample.Write("Hello World 2!"); // In die Textdatei


            // Warte erneut auf Eingabe

            System.Console.ReadLine();

        }

    }

Diesmal funktioniert alles so wie es soll. Das Beispiel ist einfacher als das von MSDN. Glaubt ihr, das kann man so lassen? Oder hat wer noch Verbesserungsvorschläge?

LG

Einfacher ja, aber nicht im Sinne von Dispose ;)

Du benutzt einen StreamWriter, dieser verwendet native Ressourcen und implementiert daher bereits IDisposable.

Daher brauchst Du in Deiner Klasse nicht nochmal in den Prozess des "Finalizers" einzugreifen, ( GC.SuppressFinalize usw). Du verzögerst dadurch nur die endgültige Speicherbereinigung.

Das Interface in dieser Art brauchst Du nur zu implementieren wenn Du direkt auf native Ressourcen (z.B. WindowHandle oder FileHandle) zugreifst.

Die Klassen aus dem Framework die das machen (also z.B. der StreamWriter) machen das alles schon.

Außerdem sollte man es vermeiden die "Dispose()"-Methode direkt aufzurufen und stattdessen einen "using"-Block verwenden.

Dieser führt das Dispose nämlich im Fehlerfall aus (also im finally-Teil eines try-finally-Blocks).

Bearbeitet von realgun

Das Problem ist, dass ich noch nie mit unmanaged Ressourcen gearbeitet habe, genauso wie viele meiner Mitschüler. (auch nicht mit using-Blöcken) Deshalb hab ich beschlossen in dem Beispiel hauptsächlich den Aufbau zu zeigen (den ich so immer wieder im Internet gefunden habe) und den Rest so zu erklären.

Eine Frage habe ich aber noch:

GC.SuppressFinalize(this); sagt dem GC doch, dass er dieses Objekt/Variable/etc kennzeichnen soll um sie beim nächsten Durchgang des GCs zu entfernen, oder?

Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.