Forum: PC-Programmierung Probleme mit BackgroundWorker und Windows.Timer in C#


von ApplikationsEntwickler (Gast)


Lesenswert?

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?

von SvenW (Gast)


Lesenswert?

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

von ApplikationsEntwickler (Gast)


Lesenswert?

Hallo Sven, vielen Dank für deine Antwort. Was könnte getan werden, 
damit der Windows.Forms.Timer im BackgroundWorker gestartet wird?

von ApplikationsEntwickler (Gast)


Lesenswert?

Wenn ich den System.Timers.Timer benutzt entstehen andere Probleme. Im 
System.Windows.Forms.Timer werden einige Berechnung sowie Daten auf die 
Form dargestellt.

von SvenW (Gast)


Lesenswert?

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

von bluppdidupp (Gast)


Lesenswert?

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)

von tk (Gast)


Lesenswert?

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...

von ApplikationsEntwickler (Gast)


Lesenswert?

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.

von ApplikationsEntwickler (Gast)


Lesenswert?

Korrektur: Ich meine natürlich den System.Windows.Forms.Timer und nicht 
den System.WIndows.Timer.

von Tobias K. (t_k)


Lesenswert?

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

von ApplikationsEntwickler (Gast)


Lesenswert?

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?

von Borislav B. (boris_b)


Lesenswert?

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
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

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
von Tobias K. (t_k)


Lesenswert?

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?

von Tobias K. (t_k)


Lesenswert?

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...

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

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
von c-hater (Gast)


Lesenswert?

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.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

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
von Tobias K. (t_k)


Lesenswert?

Tobias K. schrieb:
> @Torsten:
> Warum sollte man Invoke hassen?

Kann ich die Frage nochmal aufwärmen? Interessiert mich wirklich :)

: Bearbeitet durch User
von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.