5 Stimmen

.NET DataGridView-Steuerelement verbraucht TONNEN von Speicher für mich

Ich verwende ein DataGridView-Steuerelement in meiner app im Moment, und ich bin ein seltsames Speicherproblem mit ihm zu schlagen. Ich bin nicht mit DataBinding überhaupt, nur manuelle Bevölkerung. Die Daten, die ich in dort setzen ist nicht eine Menge überhaupt. Wir sprechen über 20 Zeilen mal 20 Spalten von Daten in der Regel am meisten.

Der Arbeitsablauf für dieses Steuerelement ist, dass ich eine ComboBox mit verschiedenen "Datensätzen" habe, die ich lade, wenn Sie sie auswählen. So eine gemeinsame Nutzung Szenario ist Zyklus durch die Datensätze in der ComboBox und sehen sie in der dataGrid rendern. Was ich sehe, ist, dass, wenn die Leute durch die Datensätze Zyklus, die app Speichernutzung springt von 100MB bis 1100MB sofort und fällt dann wieder nach unten, wenn GC kicks in. Aber wenn Sie Zyklus durch die Datensätze schnell (d.h. schneller als die GC kicks in), werden Sie aus dem Speicher laufen und die app wird sterben.

Nach der Fehlersuche habe ich herausgefunden, dass der Hauptgrund, warum der Speicher wie verrückt ansteigt, darin liegt, dass ich einige Spalten in dieser Datentabelle habe, die vom Typ Bild sind. Ich verwende sie, um ein 16x16-Symbol anzuzeigen, das den Status für diese Zeile angibt. Diese Symbole sind in einer ImageList gespeichert, und ich setze sie einfach als Wert für diese Zelle, wenn ich die Zeilen der Datentabelle ausfülle. Wenn ich die Bilder herausnehme und sie durch einfachen Text ersetze, sehe ich absolut keine Speicherspitzen.

Worum geht es hier also? Warum verursachen Bilder, winzige 16x16, die Kontrolle zu gehen verrückt auf meine mit Speicher wie das?

Mehr Informationen:

Meine Logik ist, dass Sie die Datensätze wechseln:

  • Alle Zeilen des Gitters löschen: dataGrid.Rows.Clear();
  • Alle Spalten löschen: dataGrid.Columns.Clear();
  • Fügen Sie die Spalten zum DataGrid-Steuerelement hinzu: (die meisten vom Typ String, und einige DataGridViewImageColumn)
  • Fügen Sie die Daten, die ich habe, zeilenweise mit dataGrid.Rows.Add(object[] data); (die Daten enthalten die Bilder, die ich als Symbole verwenden muss).

2voto

Will Marcouiller Punkte 23205

Das DataGridView-Steuerelement ist für die Arbeit mit DataBinding gedacht. Wenn Sie DataBinding überhaupt nicht verwenden, schlage ich vor, Sie verwenden ein ListView-Steuerelement.

Die ListView ist für die Anzeige von Bildern optimiert. Außerdem benötigt es weniger Speicherplatz als das DataGridView. Außerdem können Sie mit dem ListView-Steuerelement Ihre Ansicht ändern:

  1. ListView.View = View.Details;
  2. ListView.View = View.LargeIcons;
  3. ListView.View = View.List;
  4. ListView.View = View.SmallIcons;
  5. ListView.View = View.Tile.

Dies sind die Ansichten, die Sie in Ihrem Windows Explorer sehen können. Sie müssen nur eine LargeIcons ImageList oder eine SmallIcons ImageList oder eine von beiden definieren, je nachdem, welche Ansicht Sie Ihrem Benutzer erlauben wollen.

Sie können die GridLines auch wie ein DataGridView anzeigen, um den gleichen Effekt zu erzielen.

0 Stimmen

Hmm ... An diese Möglichkeit habe ich noch nicht gedacht. Es sollte recht einfach sein, das dataGrid durch eine ListView zu ersetzen. Ich werde das mal ausprobieren und sehen, was passiert. Vielen Dank für die Antwort!

0voto

aastle Punkte 21

In Ihrem 3. Absatz sagen Sie, dass Sie Ihre Icons in einer ImageList haben, aber in Ihrer Aufzählung von logischen Schritten sagen Sie, dass Sie die Bilder hinzufügen, die Sie als Icons als Array von Objekten benötigen. Könnte die ImageList, die dem dataGrid hinzugefügt wurde, der Fehler sein?

0 Stimmen

Das DataGrid hat eine Add-Methode, die eine ganze Zeile in Form eines Objektarrays annimmt. Für die Spalten in dieser Zeile füge ich also das gewünschte Symbol hinzu, indem ich es in meiner Bildliste wie folgt festlege: ImageList.Images[x]. Es kommt also alles aus dieser imageList. Ich habe versucht herauszufinden, ob es eine Möglichkeit gibt, die ImageList an das DataGridView anzuhängen, aber das ist nicht möglich.

0voto

Nazeeh Punkte 591

Übrigens habe ich beschlossen, dies auf eine andere Weise zu tun. Ich habe auf die benutzerdefinierte Malerei zurückgegriffen, um meine Symbole in der Zelle zu malen. Das hat viel besser funktioniert. Mit dieser Lösung frisst das Gitter keinen Speicher mehr.

Die Verwendung einer ListView war möglich, aber nicht sehr praktisch, da sie nur das Einfügen von Symbolen in die erste Spalte unterstützt. Ich hätte also sowieso ein eigenes Bild erstellen müssen.

0 Stimmen

Sie müssen Unterpunkte hinzufügen, wenn Sie Spalten hinzufügen möchten.

0voto

Ehz Punkte 1972

Ich bin auf diesen Fehler gestoßen und er scheint durch den Verweis auf ein Bild aus einer ImageList verursacht zu werden. Um dies zu umgehen, habe ich stattdessen die als Inhalt angezeigten Bilder im Projekt erstellt. Ich habe dann die Bildwerte in der Datentabelle mit Bitmap.FromImage("images/test.png") gesetzt und dieser seltsame Speicherfehler ist verschwunden.

0voto

Frank Ball Punkte 993

Datagridviews scheinen ein Speicherleck zu haben, wenn es um Bilder geht. Setzen Sie vor dem Laden Ihrer Daten die Datenquelle des Datagridviews auf null und führen Sie dann ein Dispose (mit GC.Collect()) für die Datenquelle aus.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X