Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

Wie kann sichergestellt werden, dass Dispose auch bei Fehlern aufgerufen wird? [==> using]

Moderationshinweis von gfoidl (25.11.2011 - 19:24)

Abgeteilt von Dispose implementieren und verwenden (IDisposable)

Gelöschter Benutzer

Wie kann sichergestellt werden, dass Dispose auch bei Fehlern aufgerufen wird? [==> using]

beantworten | zitieren | melden

1. wie sieht es denn eigendlich mit objekten aus, die idisposable implementieren, in einem thread verwendet werden und innerhalb eines usings gerde sind?

wenn der thread seine abarbeitung plötzlich abbricht, wird dann dispose trotzdem noch aufgerufen?

2. noch etwas:
sehr oft sieht man


//objekt das Dispose implementiert instanziieren...
myDisplosableObject o = new myDisplosableObject();
//... einige operationen.
o.Dispose():

wie wird es da gehandhabt, wenn der abbruch mitten drinn eintritt?

meine vermutung: (ich brauch dafür aber noch eine bestätigung^^)
fall 1: dispose wird aufgerufen
fall 2: dispose wird nicht aufgerufen

wenn es sich aber nur um speicher handelt, dann wird er beim beenden des programmes dennoch freigegeben oder? wie sieht es denn mit unverwaltetem speicher aus? wird dieser auch beim beenden mit freigegeben?
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo JAck30lena,
Zitat
wenn der thread seine abarbeitung plötzlich abbricht, wird dann dispose trotzdem noch aufgerufen?


using (MyDisposableObject mdo = new MyDisposableObject ()) {
   ...
}

ist m.E. äquivalent zu


{
   MyDisposableObject mdo = new MyDisposableObject ();
   try {
      ...
   }
   finally {
      mdo.Dispose ();
   }
}

Wenn du mit "Abbrechen" Thread.Abort und nicht Process.Kill meinst, wäre die Antwort also ja.
Zitat


//objekt das Dispose implementiert instanziieren...
myDisplosableObject o = new myDisplosableObject();
//... einige operationen.
o.Dispose():
wie wird es da gehandhabt, wenn der abbruch mitten drinn eintritt?
Dispose wird dann nicht ausgeführt. Dabei ist es ganz egal welcher Art der Abbruch ist. Schon ein simples return würde die Ausführung von o.Dispose verhindern.
Zitat
wenn es sich aber nur um speicher handelt, dann wird er beim beenden des programmes dennoch freigegeben oder?
Wenn Dispose richtig implementiert wird, werden die vom Objekt gehaltenen Ressourcen - egal welcher Art - im Zuge der Arbeit des GC mitfreigegeben und damit oft schon vor dem Beenden des Programms. Der GC ruft dabei den Destruktor auf und der eben Dispose.

BTW: Dispose gibt nur die vom Objekt gehaltenen Ressourcen frei. Dispose gibt nie den Speicher des Objekts selbst frei. Das kann nur der GC.

herbivore
private Nachricht | Beiträge des Benutzers
Gelöschter Benutzer

beantworten | zitieren | melden

erstmal danke für die antworten.

in diesem fall:
Zitat
wenn es sich aber nur um speicher handelt, dann wird er beim beenden des programmes dennoch freigegeben oder?
meinte ich eher folgendes szenario:

1.

//objekt das Dispose implementiert instanziieren...
myDisplosableObject o = new myDisplosableObject();
// hier ein abbruch durch abort.
o.Dispose(): 
innerhalb des dispose wird unverwalteter speicher freigegeben.
was macht der gc?
was passiert mit dem speicher nach beenden des prozesses?
svenson
myCSharp.de - Member



Dabei seit:
Beiträge: 8.746
Herkunft: Berlin

beantworten | zitieren | melden

Zitat von JAck30lena
innerhalb des dispose wird unverwalteter speicher freigegeben.
was macht der gc?

Gar nix.
Zitat
was passiert mit dem speicher nach beenden des prozesses?

Der wird in jedem Fall freigegeben. Dafür sorgt entweder der Finalizer oder - wenn der nicht aufgerufen wird - Windows selbst. Windows gibt seine eigenen (!) Ressourcen bei Prozessende frei.

Vorsicht ist nur geboten, wenn Ressourcen verwendet werden, die Windows nicht im Zugriff hat. Angenommen du hast eine Ressource auf einem entfernten Rechner allokiert, so geschieht hier natürlich nix automatisch. Hier musst du unter allen Umständen dafür sorgen, dass du solche Ressourcen korrekt via Finalizer abräumst und du mußt - soweit möglich - dafür sorgen, dass die Finalizer bei Prozessende aufgerufen werden.

Cooperative Application Shutdown with the CLR
private Nachricht | Beiträge des Benutzers
Gelöschter Benutzer

beantworten | zitieren | melden

ok also der fall das man irgendwie "tote" speicherbereiche provozieren kann, die nur noch durch einen reboot wieder genutzt werden können, kann nicht eintreten.

schlussfogerung: alles was Dispose hat UNBEDINGT in ein using rein.
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 49.486
Herkunft: Berlin

beantworten | zitieren | melden

Hallo JAck30lena,
Zitat
ok also der fall das man irgendwie "tote" speicherbereiche provozieren kann, die nur noch durch einen reboot wieder genutzt werden können, kann nicht eintreten.
richtig, spätestens beim Prozessende wird der gesamte Speicher der Prozesses freigegeben.
Zitat
schlussfogerung: alles was Dispose hat UNBEDINGT in ein using rein.
Ich würde sagen: Alles was Dispose hat nach Möglichkeit in ein using rein. Denn using kann man nur dann benutzen, wenn das Objekt innerhalb des gleichen Codeblocks zerstört werden soll, in dem es erzeugt wurde. Nun gibt es aber auch bei Objekten, die Dispose implementieren, Situationen, in denen es besser ist, ein Objekt nur einmal zu Beginn des Programms zu erzeugen und erst am Ende zu zerstören. Zum Beispiel ist es besser einen Brush oder Pen nur einmal zu erzeugen und immer wiederzuverwenden, statt ihn im OnPaint per using jedesmal neu zu erzeugen und zu zerstören.

herbivore
private Nachricht | Beiträge des Benutzers