Hallo, für einen automatischen Ablauf benötige ich einen BackgroundWorker der einen Timer starten soll. Es handelt sich hierbei um einen System.Windows.Timer. Dieser wird auch beim manuellen Ablauf eingesetzt. Nun habe ich folgenden Effekt festellen können: Sobald der BackgroundWorker gestartet wird, wird der System.Windows.Timer nicht gestartet. Nur wenn ich zum Beispiel die Zeile MessageBox.Show("...") im BackgroundWorker einfüge, dann wird der Timer gestartet. Wo könnte da das Problem liegen?
Hallo, ich denke dein Timer fällt dem Garbage Collector zum Opfer. Dein Thread wird gestartet, im Thread dann der Timer. Aber der Timer hält natürlich die Verarbeitung im Thread nicht an. Also wird der Thread beendet und dein Timerobjekt entsorgt. MfG Sven
Hallo Sven, vielen Dank für deine Antwort. Was könnte getan werden, damit der Windows.Forms.Timer im BackgroundWorker gestartet wird?
Wenn ich den System.Timers.Timer benutzt entstehen andere Probleme. Im System.Windows.Forms.Timer werden einige Berechnung sowie Daten auf die Form dargestellt.
Ich würde die Logik umstellen. Deine Form hat den Timer und der Tick des Timers startet den BackgroundWorker. Im [BackgroundWorker]_DoWork-Handler machst du deine Berechnungen und im [BackgroundWorker]_RunWorkerCompleted-Handler zeigst du das Ergebnis deiner Berechnung an. MfG Sven
ApplikationsEntwickler schrieb: > System.Windows.Timer ...rufst du den 1) per Invoke auf (richtig) 2) oder direkt einfach so? (falsch) bzgl. 1:
1 | this.Invoke(new MethodInvoker(() => { meinTimer.Start(); })); |
...dadurch wird meinTimer.Start() im UI-Thread statt im Backgroundworker-Thread ausgeführt (sofern "this" eine Form ist ;D)
Grundsätzliche Frage: Soll der Timer irgendwas mit UI machen oder im Hintergrund ohne UI laufen? Nicht direkt UI-relevante Sachen blockierend im UI Thread auszuführen ist eigentlich nie eine gute Idee...
Es handelt sich hierbei wie gesagt um einen System.WIndows.Timer. In diesem Timer werden Daten zur Visualisierung an die GUI weitergegeben. Einige Berechnung werden auch in diesem Timer gemacht. Wie kann man von einem BackgroundWorker Thread nun diesen Timer ausführen? Ein System.Timers.Timer lässt sich ohne Probleme starten. Leider möchte ich nicht diesen Timer verwenden.
Korrektur: Ich meine natürlich den System.Windows.Forms.Timer und nicht den System.WIndows.Timer.
ApplikationsEntwickler schrieb: > Wie kann man von einem BackgroundWorker Thread nun diesen Timer > ausführen? gar nicht, das macht keinen Sinn. lies dir mal das hier durch: https://msdn.microsoft.com/en-us/magazine/cc164015.aspx
Ok. Dann müsste ich mir einen anderen Weg überlegen. Ich benötige einen Ratschlag für meine derzeitige Applikation. Für die zyklische Verarbeitung/Berechnung von Daten benötige ich einen Timer. Welcher Timer sollte ich benutzen? 1) System.Windows.Forms.Timer <-- kommt nicht mehr in Frage! 2) System.Timers.Timer 3) System.Threading.Timer Die verarbeitenden bzw. berechneten Daten möchte ich auch noch auf einer Form visualisieren. Wie sollte ich die Daten in einem Timer mit der GUI synchronisieren?
Warum nimmst du nicht einfach einen eigenen Thread?
1 | private void MyThread() |
2 | {
|
3 | while(!mCancelThread) |
4 | {
|
5 | ProcessData(); |
6 | UpdateForm(); |
7 | Thread.Sleep(mCycleTimeMs); |
8 | }
|
9 | }
|
Beim Updaten der Form natürlich Invokes verwenden...
:
Bearbeitet durch User
ApplikationsEntwickler schrieb: > Ich benötige einen Ratschlag für meine derzeitige Applikation. Geht es immer noch die gleiche Applikation wie im Beitrag "Ratschlag für C# Applikation" ? Jede Woche ein neuer Thread? Das gibt jetzt bestimmt Mecker, ist aber eine Geschmachsfrage und ein Vorschlag für Invoke-Hasser: Du kannst auch im BackgroundWorker mit Thread.Sleep() arbeiten und die GUI über das ProgressChanged-Ereignis aktualisieren. Dieser Ereignis-Handler läuft dann ganz von allein im GUI-Thread, also ohne 'Invoke()'. ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ Daten kannst Du mit ProgressChangedEventArgs.UserState übergeben, ProgressPercentage kann ein Dummy-Wert sein, aber man kann ProgressPercentage nicht komplett weglassen. ApplikationsEntwickler schrieb: > System.Windows.Forms.Timer <-- kommt nicht mehr in Frage! Warum? Im Prinzip gehen alle drei. Aber dann brauchst Du halt 'Invoke()', wurde ja schon gesagt.
:
Bearbeitet durch User
Boris P. schrieb: > ProcessData(); > UpdateForm(); > Thread.Sleep(mCycleTimeMs); da hängt die Intervallzeit aber dann direkt von der Dauer von ProcessData() ab, das kann egal sein, muss aber nicht und ist mMn der große Unterschied zu Timern hier. @Torsten: Warum sollte man Invoke hassen?
ApplikationsEntwickler schrieb: > Welcher Timer sollte ich benutzen? > > 1) System.Windows.Forms.Timer <-- kommt nicht mehr in Frage! > 2) System.Timers.Timer > 3) System.Threading.Timer Hast du dir die genannte Seite und das Bsp dazu angeschaut? Der Code macht genau das...
Tobias K. schrieb: > das kann egal sein, muss aber nicht und ist mMn der > große Unterschied zu Timern hier. Auf den ersten Blick ja. Als ich das mal so umgesetzt habe, habe ich 'mCycleTimeMs' jedes Mal neu anhand der absoluten Zeit berechnet, dann bleiben auch die Abstände gleich. Für MIDI brauche ich sehr genaue Timer. Das exakte Timing lässt sich dadurch umsetzen, dass nach dem Sleep in einer While-Schleife auf das Erreichen der nächsten absoluten Zeit-Marke gewartet wird.
:
Bearbeitet durch User
Torsten C. schrieb: > Auf den ersten Blick ja. Als ich das mal so umgesetzt habe, habe ich > 'mCycleTimeMs' jedes Mal neu anhand der absoluten Zeit berechnet, dann > bleiben auch die Abstände gleich. Höchstens im Mittel, der Jitter ist aber fürchterlich. Windows ist ein präemptives Mutitasking-System. Wenn dein Thread gerade schläft, kann er auch nicht auf das Überschreiten der nächsten absoluten Grenze reagieren. > Für MIDI brauche ich sehr genaue Timer. Dann mußt du die dafür verwenden, die für solche Zwecke gedacht sind. Du findest sie in DirectShow.
c-hater schrieb: > Höchstens im Mittel, der Jitter ist aber fürchterlich Den Jitter gibt es ohne die While-Schleife. Ich erinnere mich wieder: In der Schleife habe ich den Zeitstempel mit einer StopWatch verglichen, da nur die StopWatch genau genug war. c-hater schrieb: > DirectShow Schau ich mir mal an, vielleicht ist das effizienter als While-Schleife + StopWatch.
:
Bearbeitet durch User
Tobias K. schrieb: > @Torsten: > Warum sollte man Invoke hassen? Kann ich die Frage nochmal aufwärmen? Interessiert mich wirklich :)
:
Bearbeitet durch User
Tobias K. schrieb: > Tobias K. schrieb: >> Warum sollte man Invoke hassen? > Kann ich die Frage nochmal aufwärmen? Interessiert mich wirklich :) Es ist meine Beobachtung, dass sich einige damit schwer tun. Wenn ich z.B. meine Tochter frage, warum sie kein Gemüse mag, zuckt sie immer mit den Schultern. Ich weiss es auch nicht. PS: Vermutung: Es wirkt auf den ersten Blick kompliziert. Ist es aber nicht, ich weiß.
:
Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.