Gå til innhold

Anbefalte innlegg

Hei

 

Jeg lurer litt på det rundt garbage collection. Hvis jeg har en app som skriver til fil og programmet klikker før den har lukket filen, hva skjer da? Er det noe automatikk i C# å rydde opp noe her?

 

Vil et programs destructor kalles når programmet klikker? Evt hvordan rydde opp hvis det skjer en crash?

 

Bør jeg alltid ha en destructor i alle app man lager?

 

håper på noen oppklaringer :) (forstod ikke helt sammenhengen i artiklene jeg googlet etter ang dispose)

Lenke til kommentar
Videoannonse
Annonse

en destructor er en metode som kalles av GC når den bestemmer seg for å destruere objektet ditt, og du kan ikke kalle den selv. Det er fint for enkle oppryddingsoppgaver, men hvis du har åpne resurser som file handles bør du implementere IDisposable og metoden Dispose(), hvor du kan lukke alle filresurser.

 

eventuelt kan du lukke resursen i en destruktør hvis du bruker using(), på denne måten:

class FileHandler
{
 // andre ting
 ~FileHandler()
 {
 if (this.FileHandle != null)
	 this.FileHandle.Close();
 }
}
static void Main()
{
 using(FileHandler fh = new FileHandler())
 {
// gjør noe her
 } // her vil objektet bli disposed av GC
}

 

OBS: hvis du bruker IDisposable bør du også kalle GC.SuppressFinalize(this).

 

For å lukke resurser som filer kan det f.eks. gjøres lik:

using System;
class FileHandler : IDisposable
{
  bool is_disposed = false;
  protected virtual void Dispose(bool disposing)
  {
	if (!is_disposed) // only dispose once!
	{
	  if (disposing)
	  {
	Console.WriteLine("Not in destructor, OK to reference
other objects");
	  }
	  Console.WriteLine("Disposing...");
	}
	this.is_disposed = true;
  }
  public void Dispose()
  {
	Dispose(true);
	GC.SuppressFinalize(this);
  }
  ~Testing()
  {
	Dispose(false);
	Console.WriteLine("In destructor.");
  }
}

Du kan også legge til en Close()-metode som kaller Dispose, hvis du syns det gir mer logisk mening enn navnet Dispose().

 

EDIT: using-statements kaller visst Dispose(), ikke destruktøren som jeg trodde.

 

og EDIT igjen: nei, du kan med god samvittighet droppe destruktører når du ikke håndterer resurser som krever eksplisitt lukking.

Endret av hockey500
Lenke til kommentar
IDisposable er ment for hvis du bruker enten unmanaged ressurser eller database koblinger.

Vanlige.

 

Vanlige .NET klasser blir fikset av GC.

 

Ja, men man vet ikke "når" hvis man ikke bruker using() eller .Dispose();

 

Tommelfingelregel: ALLTID bruk using() på klasser som implementerer IDisposable.

 

F.eks.:

 

using(StreamReader sr = System.IO.File.OpenText("test.txt"))

{

sr.ReadLine();

// etc...

}

Lenke til kommentar
Takk for mer eller mindre forståelige svar:)

 

Men hva menes med "klasser som implementerer IDisposable"? Hvilke typiske klasser er dette?

 

Du har flere muligheter for å sjekke dette:

* Les dokumentasjonen

* Se om du kan kjøre .Dispose(); på objektet. Hvis du kan det så implementerer den IDisposable

* Høyreklikk på klassen i Visual Studio - Go to definition. Sjekk klassen og alle klasser den arver av for å se om de implementerer IDisposable

Lenke til kommentar

Typiske klasser som implementerer IDisposable er fil, grafikk, nettverk og lignende ressurser. Objekter som kan innholde store mengder data og hvor det er anbefalt å rydde opp etter seg når en er ferdig, både for å frigjøre kapasitet men også gi andre tilgang til den samme ressursen.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...