C# - Wie Endlosformular realisieren?

kasal

Erfahrenes Mitglied
Hallo Freunde,

Ich versuche in C# ein Endlosformular zu realisieren (so wie in Microsoft Access). Ich habe da auch schon einiges probiert, jedoch bin ich nicht sehr weit gekommen.

Ich habe eine Tabelle (Microsoft SQL Server), deren Inhalt ich mir in eine DataTable lade. Nun habe ich ein Panel erstellt, in dem ich für jeden DatenSatz ein eigenes Panel erstelle (siehe Bild). Soweit so gut - das klappt auch... wenn man 10 Datensätze oder so hat.

Jedoch befinden sich in der Tabelle gegenwärtig ca. 150'000 Datensätze! :eek:
Und das Programm brauch dann ca. 250 MB Arbeitsspeicher!

Wenn ich das ganze dagegen mit Access realisere funktioniert das ohne Probleme, er stellt alles schnell da und braucht dagegen nur ca. 30 MB Arbeitsspeicher.

Vielleicht hat jemand von euch so etwas schonmal realisiert und kann mir helfen. :)
Vielen Dank schonmal im Vorraus!!


Gruss,
kasal
 

Anhänge

  • panel.PNG
    panel.PNG
    1,7 KB · Aufrufe: 59
Hallo,

Ich habe eine Tabelle in der sind Aufträge drin und ich möchte so ne Art Bestandsliste darstellen (alle Aufträge die grad im System erfasst sind).

Und die möchte ich möglichst "ansprechend" darstellen sag ich mal. Das DataGrid Control bildet ja die Tabelle lediglich so wie sie ist auf meinem Form ab. Ich möchte aber in jedem Datensatz noch Steuerlemente, Kontextmenues etc. verwenden.


Gruss,
kasal
 
Dann lass mal dein Programm durch den CLR Profiler laufen und schau wo wirklich wieviel Speicher verbraucht wird.
http://www.microsoft.com/downloads/...52-d7f4-4aeb-9b7a-94635beebdda&displaylang=en

Die Erklärung bei Wiki ist zwar kurz aber gut:
http://en.wikipedia.org/wiki/CLR_Profiler

Das Programm ist zwar Anfangs etwas verwirrend, aber gut.

Wieviel Panels hattest du eigentlich auf dem Formular als 250MB belegt wurden?

Aber ich vermute stark du solltest die Datensätze eher Stückweise laden und anzeigen.
 
Hallo kasal,

wenn Du 150000 Datensätze gleichzeitig lädst, ist es nicht verwunderlich, dass der benötigte Arbeitsspeicher ziemlich groß wird.
In solchen Fällen ist es sehr wichtig, nicht mehr benötigte Ressourcen sofort freizugeben. In Deinem Fall bedeutet das: nur die Steuerelemente, die auch sichtbar sind, sollten existieren, während die anderen sofort per Dispose aus dem Speicher entfernt werden sollten. Reagiere dazu entsprechend auf das Scroll-Event Deiner vertikalen Bildlaufleiste. Zudem wäre es hilfreich, im SizeChanged-Event des Anzeige-Containers die maximale Anzahl sichtbarer Einträge zu ermitteln (also Gesamthöhe, dividiert durch die Höhe eines Eintrags; bei unterschiedlicher Eintragshöhe entsprechend etwas komplizierter) und in einer klasseninternen Variablen zu speichern.

OK, ich hoffe, ich konnte Dir einen Anreiz für die Umsetzung bieten. Falls Fragen auftauchen, melde Dich hier wieder.

Gruß
PhoenixLoe
 
Hallo,

erstmal vielen Dank für eure Antworten - konnte leider bisher nicht zurückschreiben.

Es werden nun nur noch die Steuerlemente angezeigt, die im Sichtbareb bereich liegen (Anhand der Bildlaufleiste weis ich das nun).

Allerdings bleibt da noch das Problem mit dem Speicher. Ich lade zu beginn alles in eine BindingSource (was den hohen Speicherbedarf erklärt).

Ich hab mal eine Access mdb gemacht die mir die selbe Tabelle im Endlosformular anzeigt. Geht echt schnell und brauch nur ein paar MB Speicher.

Spyke meinte man könnte die Datensätze schrittweise je nach bedaf laden (Ich vermute mal, dass es Access genauso macht).

Wie kann ich das jedoch in C# realisieren


Viele Grüße,
kasal
 
Hallo Freunde,

hat wirklich keiner ne Idee
Ich habe es nun mal so weit hinbekommen, dass er nur mal die ersten 50 Datensätze liest. Das Fenster erscheint schnell, er zeigt die Daten sauber an. Wenn man jedoch runterscrollt müssten weitere Datensätze nachrücken und andere, die im Moment nicht sichtbar sind, verschwinden. Doch wie löse ich das? :confused:
Vielleicht hat einer von euch nen denkanstoss für mich..

Vielen Dank schonmal im Vorraus!


Grüsse,
kasal
 
Zuletzt bearbeitet:
Ich glaube ich würde mir die letzte gelieferte Id merken und von der aus die nächsten 50 liefern lassen.
Ungefähr so:
Code:
SELECT * FROM Tabelle Where ID>@MeineId HAVING COUNT(Id)<50
Sql Anweisung ist bestimmt nicht richtig, mein Kopf ist grad bissel leer, aber denke mal die Grund IDee ist verständlich.

Hier ist natürlich vorrausetzung das alles nach Id sortiert ist.
 
Ich löse das, allerdings mit einem DataGridView, indem dem ich dieses in den VirtualMode versetze. Dann werden nur die Datensätze geladen, die gerade angezeigt werden sollen.

Code:
 this.dataGridView1.VirtualMode = true;
// Connect the virtual-mode events to event handlers. 
this.dataGridView1.CellValueNeeded += new DataGridViewCellValueEventHandler(dataGridView1_CellValueNeeded);

Hier noch ein bisschen mehr Infos dazu:
http://dzaebel.net/DgvVirtual.htm


Mit DataGrids kann man ja schon mehr machen, als eine reine Tabelle abbilden. Einige Steuerelemente sind ja schon vorhanden, wenn nicht kann man sich auch eigene erstellen:
http://msdn.microsoft.com/de-de/library/bxt3k60s.aspx
http://www.codeproject.com/KB/miscctrl/GenericDataGridView.aspx?msg=2017875

Grüsse
 
Zurück