Autor Beitrag
nesh
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Di 31.07.12 16:49 
Hallo Forumsmitglieder,

ich habe folgendes Problem.

Ich möchte 2 Datenbanken/Tabellen abgleichen.
Es handelt sich dabei um 2 Tabellen (Artikelstammdaten) bei denen ich von der Master DB den Bestand in eine andere Tabelle schreiben möchte.
Das Problem welches auftritt ist, dass das Programm nach ca. 40.000 Datensätzen eine exeption wirft. Der Belegte RAM beträgt dann ca. 1,5GB.

Um nicht den ganzen Code zu posten hier mal ein Auszug wie ich das prinzipiell mache:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
//Benötigte Daten von Masterdb in ein Array einlesen
List<string[]> Masterdaten = (from mdata in Masterdb select new string[]{mdata.Artikelnummer,mdata.Bestand}).ToList();

//Die erhaltenen Datensätze (ca. 95.000) nun in der Slavetabelle Suchen und den Bestand schreiben

foreach(string[] s in Masterdaten)
{
  //Datensatz auswählen
  Slavetabelle Datensatz = Slavetabelle.SingleOrDefault(l=>l.Artikelnummer == s[0]);
  Datensatz.Bestand = s[1];
  Slavetabelle.SubmitChanges();
  //Bei jedem Durchlauf kommen ca. 500KB Ram hinzu
}

Das klappt soweit einwandfrei. Warum aber baut sich jedoch der RAM so weit auf bis dann die exeption geworfen wird??
Meine Vermutung ist das die Variable Datensatz intern nicht gelöscht bzw. frei gegeben wird.
Das ist aber nur meine Vermutung.
Habt Ihr eine Idee oder einen Tip oder gar die Lösung für mich?

Ich bedanke mich schon mal für eure Mühe

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Di 31.07.12 17:51 
Hallo nesh :welcome:

zuersteinmal fällt mir auf, daß du (zumindestens für den gezeigten Codeausschnitt) unnötigerweise die Daten der Mastertabelle komplett mittels ToList() in den Speicher lädst, anstatt als IEnumerable zu durchlaufen:
ausblenden C#-Quelltext
1:
IEnumerable<string[]> Masterdaten = from mdata in Masterdb select new string[]{mdata.Artikelnummer,mdata.Bestand};					

Zum Thema LinqToSql und OutOfMemoryException gibt es einige Beiträge im Internet, besonders auf [url=www.stackoverflow.co...ckoverflow.com[/url], z.B.
stackoverflow.com/qu...t-of-objects-c-sharp
stackoverflow.com/qu...eak-with-linq-to-sql

Aus dem gezeigten Code innerhalb der Schleife kann ich jetzt keinen direkten Fehler erkennen.
Einzig, daß du jedesmal SubmitChanges() aufruft, kommt mir nicht so elegant (bzw. performant) vor - besser wäre erst ganz am Ende bzw. in bestimmten Blöcken (z.B. alle 1000 Datensätze).

Für diesen Beitrag haben gedankt: nesh
nesh Threadstarter
Hält's aus hier
Beiträge: 2



BeitragVerfasst: Di 31.07.12 21:56 
Hallo und Danke für den Willkommensgruß Th69 :-)
Du hast meinen abend gerettet.

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo nesh :welcome:

zuersteinmal fällt mir auf, daß du (zumindestens für den gezeigten Codeausschnitt) unnötigerweise die Daten der Mastertabelle komplett mittels ToList() in den Speicher lädst, anstatt als IEnumerable zu durchlaufen:

Du hast absolut recht, das macht keinen Sinn!

ausblenden C#-Quelltext
1:
IEnumerable<string[]> Masterdaten = from mdata in Masterdb select new string[]{mdata.Artikelnummer,mdata.Bestand};					

user profile iconTh69 hat folgendes geschrieben Zum zitierten Posting springen:

Zum Thema LinqToSql und OutOfMemoryException gibt es einige Beiträge im Internet, besonders auf [url=www.stackoverflow.co...ckoverflow.com[/url], z.B.
stackoverflow.com/qu...t-of-objects-c-sharp

In dem von dir geposteten Link hat mir folgender Satz geholfen:

If you don't need object tracking set DataContext.ObjectTrackingEnabled to false.

Ich habe das umgesetzt, und die Anwendung bleibt bei konstanten 23MB stehen.

Vielen Dank nochmal