Frage

Ich habe ein paar Klassen, die Verweise auf andere Klassen durch IDictionary Instanz Mitglieder halten.

Wie so:

class A
{
  private readonly Dictionary<int, B> _particles = new Dictionary<int, B>();
  public void CreateNewB(int someInt)
   {
     var b = new B();
     if (!_particles.ContainsKey(someInt)
         _particles.Add(someInt, b);
   }
}

so ist dies das Setup, und ich sie nie aus diesem Wörterbuch entfernen, aber aus irgendeinem Grund, der Destruktor für die Klasse B wird auf einem GC-LAUF ab und zu, und ich verstehe nicht, warum.

Könnte es etwas sein, zu tun, wie die Dictionary-Klasse fügt neue Referenzen?

FEST :

Ok, ich danke Ihnen allen für Ihre Antworten, ich habe sicherlich jetzt ein großes Verständnis für die GC und deconstructors gewinnen.

Aber das Problem mein eigen war, war ich das Hinzufügen someInt nur, wenn es nicht existiert bereits und durch fehlerhaft Geschäftslogik, someInt war immer 1, so das erste Mal, durch sie arbeitete und die deconstructors nicht aufgerufen. Aber das zweite Mal, allerdings wurde die „b“ Instanz einfach nicht in die Liste aufgenommen und wurde im GC Laufe gereinigt.

Nochmals vielen Dank an alle, die geholfen!

War es hilfreich?

Lösung 5

Ok, ich danke Ihnen allen für Ihre Antworten, ich habe sicherlich jetzt ein großes Verständnis für die GC und deconstructors gewinnen.

Aber das Problem meine eigen war, war ich das Hinzufügen someInt nur, wenn es nicht bereits und durch fehlerhaft Geschäftslogik nicht existiert, war someInt immer 1, so das erste Mal durch sie arbeitete und die deconstructors nicht genannt hat. Aber das zweite Mal, allerdings wurde die „b“ Instanz einfach nicht in die Liste aufgenommen und wurde im GC Laufe gereinigt.

Ich antworte dies nur schließen ihn ab)

Andere Tipps

Ihre Klasse B wird GC, wenn der Verweis auf die Klasse A ist tot

  

Ich entferne sie nie von diesem   Wörterbuch, aber aus irgendeinem Grund, die   destructor für Klasse B aufgerufen wird,

Der destructor in .NET ist nicht die gleiche wie destructor in C ++ (nicht verwaltet).
Destructor nennt Finalisierung Verfahren automatisch.

Hier sind einige Merkmale eines destructor :

  • Destruktoren können nicht in structs definiert werden. Sie werden nur mit Klassen verwendet.
  • Eine Klasse kann nur eine destructor hat.
  • Destructors kann nicht vererbt oder überlastet werden.
  • Destructors kann nicht aufgerufen werden . Sie werden aufgerufen automatisch .
  • A destructor nehmen keine Modifikatoren oder Parameter.

Also, was in Ihrem Fall geschieht, ist dies (in 2 Worten):

  1. Klasse A Garbage Collected.
  2. Als Ergebnis 1:. _Particles Feld erhalten GC-d
  3. Als Ergebnis von 2:. Einträgen im Wörterbuch wurde nicht verwurzelt (verfügbar für Garbage Collection)
  4. Als Ergebnis von 3:. Einträgen im Dictionary (Klasse B-Instanzen) sind GC-d
  

Könnte es etwas zu tun mit, wie   die Dictionary-Klasse fügt neue   Referenzen?

Nein.

Es klingt wie Sie etwas sehr falsch machen. In einer verwalteten Umgebung, um eine Referenz zu halten diese wie die Beträge im Wesentlichen für immer zu einem Speicherleck leben werden, es sei denn, Sie wirklich diese Objekte halten bedeuten rund.

Die andere Sache zu erinnern ist, dass es als destructor in C # nicht so etwas ist. Was haben Sie sind Finalizers , die unterschiedlich sind. Es ist selten, mit einem verwalteten Code, den Sie sollten auch einen Finalizer überhaupt schreiben müssen. Der einzige gute Grund, dies zu tun ist, wenn Sie IDisposable für einen Typen implementieren eine nicht verwaltete Ressource wickeln ist das nicht schon von einem Finalizerthread bedeckt .

Zum Beispiel, viele Menschen in eine Art, die IDisposable implementiert und wickelt SqlConnection als Teil ihrer Datenzugriffsschicht. Auf diese Weise können sie sich mit den Blöcken Instanzen des Typs wickeln und stellen Sie sicher, dass alle SqlConnections schaffen sie ordnungsgemäß entsorgt. Aber diese Art tut nicht muß einen Finalizer, da die zugrunde liegende Datenbankverbindung bereits von der Finalizerthread in der SqlConnection Klasse selbst abgedeckt. Es gibt keinen neuer nicht verwalteten Ressourcentyp zu, nur die SqlConnection Art zu kümmern. Aber wenn Sie eine neue Datenbank-Engine Gebäude wurden und die neuen .NET-Datenprovider für ihre Durchführung, würden Sie wollen einen Finalizer für Ihre Verbindung zu implementieren.

So habe ich den folgenden Typ:

type k {
public k() { Console.WriteLine("Hi, I'm a new K!"); }
public ~k() { Console.WriteLine("I'm a dying K!"); }
}

Und ein kleiner Code-Snippet:

Dictionary<int, k> ks = new Dictionary<int, k);
for(int i=0;i<10;i++) { ks.add(i, new k()); }

und Sie sehen, dass ~ k () an einem Punkt callled werden? Ist das, was los ist?

Ich würde mein Geld auf Klasse B Wette an anderer Stelle geschaffen. Wenn es eine Konsolenanwendung, Ausgabe etwas in B Konstruktor und Destruktor. Achten Sie darauf, dass die Anzahl der Instanziierungen ist, was Sie erwarten, dass es sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top