Timer und while-Schleife asynchron laufen lassen
-
Mein Programm läuft mit Threads wesentlich schneller als mit Application::DoEvents().
Was wird denn in der while- Schleife gemacht? Polling?
Ich habe das While-Schleifen-Problem mehrfach. Einmal werden Fließkomma-Operationen durchgeführt, einmal Integer-Operationen, einmal schreibzugriffe auf die Festplatte und einmal Lesezugriffe. Nur die Lesezugriffe haben sich nicht beschleunigt.
Das ganze Programm ist ein Benchmark-Programm.
-
Threads sind meiner Meinung nach für zwei Dinge:
1. Paralellisieren von Prozessen (im Sinne von Arbeit erledigen)
Hier macht es kein Sinn viel mehr Threads als CPU Kerne zu benutzen.
2. Um IO Operationen (File IO, Netzwerk IO, etc.), die von Natur aus viel Zeit mit Warten verbringen,
"paralell" warten lassen können (und damit andere Threads befähigen ihre Arbeit zu erledigen).In diesem Sinne ist deine Aussage logisch:
Nur die Lesezugriffe haben sich nicht beschleunigt.
Grüsse Simon
-
Hallo Doug_HH,
welche Probleme DoEvents auslösen kann haben ja Knuddelbaer und vor allem auch der verlinkte Blogeintrag von simon.gysi schon gezeigt - DoEvents täuscht einfach eine Sicherheit vor, die man nicht hat.
Der Aussage "Mit Kanonen auf spatzen geschossen" kann ich leider auch net ganz zustimmen. Klar, man muss bei Multithreading wissen was man tut und auf was man achten muss, aber das muss man überall. Ich hab oftmals das Gefühl sobald man Multithreading hört denke einige an was arg kompliziertes, dabei ist es in einfacher Ausführung eigentlich leicht Programme mit mehreren Threads zu schreiben. Sehe da nicht wo die Kanonen sind. Das es im Detail natürlich ganz schön verzwickt sein kann stimmt schon, aber das meist nur wenn Threads Daten teilen was hier nicht der Fall ist. Wenn sie für sich alleine laufen stellen sie keinerlei Stolpersteine dar.
Das es C# 3.0 ist hätt ich vielleicht zuschreiben können, stimmt schon Dachte des wäre durch Erwähnung der Lambda Ausdrücke klar gewesen.
@Mr X
Auch wenn du dich freust dass durch dein Programm wohl schneller läuft durch die Threads (was nicht zwangsläufig so sein muss), werden deine Ergebnisse wenn du Benchmarks damit veranstalten willst, nicht unbedingt genauer, da der Worker Thread der die Arbeit verrichtet ja auch gescheduled wird, und Zeit an andere Threads abgeben muss, und je nachdem wie du Zeit misst, kannst du mächtig daneben langen. Wenn du da nen Timer auf 2 Sekunden stellst und in deinem extra Thread läuft ne Schleife wo du am Ende gucken willst wie oft die durchgelaufen ist, kanns passieren das der Timer gestartet wird, der Thread startet, bekommt dann aber kaum Rechenzeit warum auch immer, der Timer stoppt den Thread, du schaust und siehst: ah ich hab 10000 Durchläufe, denkst dir du hast dein Ergebniss relativ genau, aber vielleicht war der Thread auch nur nen viertel der Zeit aktiv und das Ergebniss ist total verfälscht. Da muss man sich echt das Gesamtkonzept überlegen, wie man richtig Zeiten misst. In vielen Pseudo"bechmarks" die man irgendwo sieht um was auch immer zu vergleichen, wird das nämlich oft falsch gemacht.
-
Im Prinzip gilt dies für viele Benchmarking Programme.
Man sollte natürlich während des Benchmarks nichts machen, sonst ist das Ergebnis ungenau/falsch. Dies gilt aber für alle Benchmarking-Programme, die ich bislang ausprobiert habe.
-
Hallo Talla,
ich sehe es jetzt absolut und ohne Zweifel ein, dass man hier mit dem Threadcode arbeiten sollte und es vielleicht für andere Zwecke auch besser geeignet ist als DoEvents();
Ich habe in der Tat nicht daran gedacht, dass DoEvents die Anwendung ausbremst, was aber logisch ist, da ja die Warteschlange abgerufen wird.
Das gleiche passiert aber mit dem Threadcode auf einer „Ein-Prozessor-Maschine“.
Dem sollte man sich auch bewusst sein.Visual C# 2005 von Andreas Kühnel schrieb:
Eine Ein-Prozessor-Maschine vorausgesetzt, kann zu einem gegebenen Zeitpunkt nur ein Thread von der CPU bearbeitet werden. Stehen mehrere Threads derselben oder auch unterschiedlicher Anwendungen zur Ausführung in einer Warteschlange, erfolgt der Austausch der Threads in der CPU in sehr kleinen Zeitintervallen. Einem Anwender fällt das nicht auf – aus seiner Sicht erscheint es so, als würde die Ausführung gleichzeitig erfolgen.
http://www.galileocomputing.de/openbook/visual_csharp/visual_csharp_11_000.htm
Jetzt kurz mal zu C# 3.0.
In erste Linie wäre es nett gewesen das zu sagen, dass das C# 3.0 ist, aber das ist nicht so schlimm.
Teile der Syntax sind mir nämlich unbekannt.
Wie ich sehe hat sich die Syntax auch ein wenig geändert.Oder wie soll ich die Parameter x,y verstehen?
Oder sind das doch Variablen? Nur ich sehe keine Vereinbarung im Code.Oder => was macht der?
timer.Elapsed += (x,y) => {
Werde mir aber gleich mal mehr Info holen.
Scheint sich aber was getan zuhaben in Richtung C# wie ich es durch kurze Infos im Netz mitbekommen habe.
Gruß, Doug_HH
-
Doug_HH schrieb:
Ich habe in der Tat nicht daran gedacht, dass DoEvents die Anwendung ausbremst, was aber logisch ist, da ja die Warteschlange abgerufen wird.
Das gleiche passiert aber mit dem Threadcode auf einer „Ein-Prozessor-Maschine“.
Dem sollte man sich auch bewusst sein.Es sei mal dahin gestellt, ob ein Switschen zwischen den Threads aufwendiger und Zeitintensiver ist als ein Spinup mit DoEvents, sollte der Vergleich 2 Threads == 1 Thread mit DoEvents auf einem Core noch mal überdacht werden.
Ansonsten: Wer an dieser Stelle das Problem der DoEvents noch nicht erkannt hat und jetzt immer noch nach generellen Argumenten gegen Threads sucht (oder sogar mit 1 Core CPUs, 2 Threads mit Performancebedenken anrückt) möge sich die Problematik der DoEvents im stillen noch einmal selbst erörtern.