Laden...
D
diamond
myCSharp.de - Member
9
Themen
38
Beiträge
Letzte Aktivität
vor 13 Jahren
Dabei seit
29.06.2007
Alter
43
Beruf
Softwareentwickler
Herkunft
Deutschland
Website
Erstellt vor 13 Jahren

Dass Multi-Threading nicht unbedingt einfach ist, ist mir schon klar und ich kenne auch die Probleme, die dabei Auftreten können (sicherlich aber nicht alle). 😃
Mein Problem beruht aber mehr auf ein Missverständnis, ich hatte nämlich laienhaft gedacht, dass bei dem Aufruf "Parallel.ForEach(...)" schon alles intern berücksichtigt wird (was schon ziemlich cool wäre).
Dem ist aber leider nicht so, jetzt ist es verstanden.

Danke!

Erstellt vor 13 Jahren

Hallo Leute,

ich habe erst seit kurzem angefangen die Parallel.ForEach Lösung zu nutzen. Diese fand ich auch soweit ganz gut, bis ich feststellen musste, dass die Ergebnisse die dabei raus kommen bei jedem Durchlauf unterschiedlich sind.

Für bessere Verständnis habe ich hier ein paar einfache Beispiele wobei int-Werte zu einer Summe addiert werden.
Was haltet Ihr davon? Bzw. habe ich vielleicht einfach etwas falsch verstanden?

            List<int> zahlen = Enumerable.Range(1, 10000).ToList();
            int newSum1 = Enumerable.Range(1, 10000).Sum();                     //newSum1 == 50005000 (entspricht einer normalen ForEach Schleife)
            int newSum2 = Enumerable.Range(1, 10000).AsParallel().Sum();        //newSum2 == newSum1 (auch nicht schlecht, parallel kann also nicht ganz verkehrt sein)

            int newSum3 = 0;
            Enumerable.Range(1, 10000).AsParallel().ForAll(z => newSum3 += z);  //newSum3 != newSum1

            int newSum4 = 0;
            System.Threading.Tasks.Parallel.ForEach(zahlen, z => newSum4 += z); //newSum4 != newSum1

            int newSum5 = 0;
            System.Threading.Tasks.Parallel.For(0, zahlen.Count, z => newSum5 += z); //newSum5 != newSum1

Nutzen tu ich die Parallel.ForEach in Wirklichkeit zum Durchlaufen einer Liste mit Objekten und dort habe ich eben auch das Gefühl, dass ein Teil gar nicht durchlaufen wird, weil die Werte am Ende von den Werten einer normalen ForEach Schleife abweichen.

Kommt es evtl. zu irgend welchen Kollisionen, weil es ja parallel in unterschiedlichen Threads läuft, am Ende aber alle Threads in einer und die selbe sum-Variable addieren sollen?
Warum klappt es dann mit "int newSum2 = Enumerable.Range(1, 10000).AsParallel().Sum();"

vielleicht weiß es wer besser?

Erstellt vor 13 Jahren

😃

nur weil es bei der 2ten Variante etwas mehr Zeichen sind, muss diese nicht gleich schlicht sein.
Am Ende wird man eher eine kurze Methode Aufrufen, die entweder die eine oder die andere Lösung beinhaltet.
Und welche der beiden Lösungen am Ende gewinnt entscheidet neben deren Kürze evtl. auch die Performance (wenn da überhaupt was messbar ist).

Danke für deinen Tipp, der Schock ist zunächst vorüber 😃

Erstellt vor 13 Jahren

OK, so einfach kann das gehen!

Danke.

Eine andere Lösung wäre die folgende:

System.ComponentModel.TypeConverter converter = System.ComponentModel.TypeDescriptor.GetConverter(typeof(int));
            object obj = converter.ConvertFromInvariantString("-1");
Erstellt vor 13 Jahren

Hallo Leute,

heute habe ich eine schockierende Erfahrung gemacht! Mal sehen, wer von euch C#pern mich beruhigen kann 😃

Folgender Fall. Ein Programm speichert 100te von verschiedenen Einstellungen in eine INI Datei. Unter diesen Einstellungen sind such negative Zahlen-Werte bei.

Beim Speichern in diese INI Datei wird eine solche negative Zahl (z.B. -1) einmal ToString() gewandelt.
Beim Lesen aus der INI Datei kommt ein String "-1" welcher per Convert.ToInt32("-1") wieder zurück zu einem gültigen Int-Wert gewandelt wird.
Soweit alles keine Problem.

Jetzt kommt ein User, der in seinen Windows Region und Sprach-Einstellungen einfach mal das "Negatives Vorzeichen" von Minus "-" auf "*" geändert hat.
Ab diesem Moment ist die INI Datei für das Programm nicht mehr brauchbar,
denn ein Convert.ToInt32("-1") scheitert mit einer FormatException.
Ab diesem Moment versteht nur noch Convert.ToInt32(" *1").

Anders rum, aus Int nach String, kommt nun auch nicht mehr "-1" sondern " *1".

Also ich hab ja nichts dagegen, wenn eine User sich das Negative Vorzeichen auf etwas anderes als ein "-"-Zeichen einstellt, soll er doch machen was er für richtig hält. Das mag von mir aus auch in irgend welchen Ausgaben (Labels, Ausdrucke etc.) gut aussehen, aber als ich feststellen musste, dass C# mit Convert.ToInt32("-1") nicht mehr auf eine Zahl -1 kommt, da war ich baff.

Das war für mich fast selbstverständlich, dass C# damit umgehen kann. Fix haben wir es unterm alten Visual Basic ausprobiert, der kann damit umgehen.


C# soll einfach unabhängig von den Systemeinstellungen einen String "-1" als eine Zahl -1 erkennen und umgekehrt von -1 in einen String "-1" wandeln.

Also was sagt ihr zu diesem Problem und viel wichtiger, wie kann man es lösen?

Erstellt vor 14 Jahren

Kurzer Stand der Dinge:
heute kam ich tatsächlich auch einmal zum Testen, leider aber auch nur ein Tool.
Das Tool von DevExpress, es nennt sich XtraReports.
Ich war schon verwundert, dass nach der Installation der Demo sofort alles lief (ohne irgend welche Stolpersteine, wie es oft bei solchen Demos gibt). Die Aufmachung der Demo sieht auch sehr bemüht aus, im Vergleich zu den anderen beiden Kandidaten die ich bereits kenne und erwähnt habe.

Neben den vielen Report Demos die diese anbieten, gab es eine die für mich für diesen Fall besonders interessant war, diese nennt sich "Large Quantity of data". Diese Demo Generiert aus 100.000 Zeilen in weniger als 1Minute 2600 Seiten. Aus den nun 3 bekannten Tools ist dieses Tool von der Performance her das beste.

100.000 Zeilen waren mit aber noch zu wenig, also prompt auf 400.000 Zeilen erhöht und lass ihn generieren. Dafür brauchte das Tool etwas über 4 Minuten und generierte dabei rund 10.300 Seiten. Auch besser als die anderen, hat man hier sofort die Druckvorschau mit den generierten Seiten, während der Rest noch läuft. Das Scrollen und Zoomen ist ebenfalls sofort und vor allem ruckelfrei möglich (während er noch beim Generieren ist). Der Speicherverbrauch bei 10.300 Seiten lag bei 'nur' 700 MB, was nicht heißt, dass das Tool soviel verbraucht. Im Hintergrund ist auch noch die DataTable mit den 400.000 Zeilen.

Der nächste Kandidat wäre List & Label, diesen probiere ich demnächst auch mal aus.

Erstellt vor 14 Jahren

@gfoidl,

was in meinem Fall überhaupt nicht geht, ist etwa etwas auf die Festplatte zu cachen, in Form von Dateien. Wenn du es in diese Richtung gemeint hast, wegen XML Daten. Natürlich könnte man die XML Daten auch im Arbeitsspeicher vorliegen haben, aber dann belegen Sie ja auch einiges oder verstehe ich etwas falsch.

Außerdem muss es in meinem Fall möglich sein, die Daten vorher in einer Druckvorschau anzuzeigen, das ist auch eher der Grund weshalb es ressourcenmäßig Probleme gibt.

COne bspw. baut zunächst ein Document-Objekt auf, der nur die reinen Definitionen und Daten enthält, das wäre noch nicht so schlimm, aber dann muss es auf's Blatt bzw. in die Druckvorschau. In dem Moment fängt die Malerei an und es verbraucht noch einmal mind. genau soviel Arbeitsspeicher. Es kann also passieren, dass man im Hintergrund ein Document-Objekt mit 10.000 Seiten hat (was sehr viel wäre), dann freut man sich aber leider zu früh, den das Objekt belegt schon mehr als 1GB im Arbeitsspeicher. Davon bekommt man dann vielleicht nur 1000 Seiten generiert und hat nix gewonnen.
Es wäre vielleicht schlauer die Seiten erst auf Anforderung zu generieren, also wenn man bspw. in der Druckvorschau blättert, geht aber leider wieder nicht, wenn man es ohne Druckvorschau direkt an den Drucker senden möchte. Ist auch etwas, wo wir leider auch keinen Einfluss drauf haben, da wir nicht bei COne arbeiten 😃
Dies nur so als Beispiel zur näheren Verständnis.

Die meisten von Euch kennen doch sicherlich MS Excel

Generiere dort einfach Dummy Daten in 1Mio. Zeilen in klicke auf Seitenansicht-
Die Ansicht ist in 3sekunden auf dem Bildschirm und hat weit über 10.000 Seiten.
Wenn man jetzt auf Drucken klickt, dauert es noch einmal 10sek.

So etwas suche ich (völlig egal wie sie das im Hintergrund lösen).
Wahrscheinlich könnte man auch was eigenes Programmieren, etwa mit PrintDocument und PrintPreview, aber da Sitz man dann sicherlich auch eine Weile dran und wird am Ende noch 100te Fälle nicht bedacht haben.

Erstellt vor 14 Jahren

@herbivore,

hätte ja sein können, dass jemand mal vor dem gleichen Problem stand und heute einfach mal besser informiert ist als ich.
Ich suche ja schließlich nicht irgend welche Reporting Tools, sondern solche die möglichst viele Seiten mit möglichst wenig Speicherverbrauch schaffen, was eher eine Seltenheit ist. Die meisten drucken irgend welche Rechnungen oder Formulare und niemals über 3500 Seiten (mein Rekord mit Active Reports 6).

Erstellt vor 14 Jahren

@zommi,

ich denke nicht, dass ich mich selbst an das Ausrechnen ran wagen möchte 😃

Der Beitrag unter deinem Link ist aber sehr interessant, danke für den Hinweis. 😃

Erstellt vor 14 Jahren

Ich würde gern wissen, was ein Objekt oder ein Array mit Objekten tatsächlich an Speicher belegt. Welche gute Möglichkeiten kennt Ihr?