Ich habe einen Timer, der seinen Handler für verstrichene Ereignisse nicht gleichzeitig verarbeiten muss. Aber die Verarbeitung eines verstrichenen Ereignisses kann mit anderen stören. Ich habe die folgende Lösung implementiert, aber etwas stimmt nicht. Es scheint entweder, ich sollte den Timer anders verwenden oder ein anderes Objekt innerhalb des Threading-Bereichs verwenden. Der Timer schien am besten zu passen, da ich regelmäßig nach einem Status suchen muss, aber manchmal dauert die Überprüfung länger als mein Intervall. Ist das der beste Weg, um das zu erreichen?Wie kann ein Timer während der Verarbeitung des verstrichenen Ereignisses blockiert werden?
Antwort
Sie könnten AutoReset auf false setzen und dann den Timer explizit zurücksetzen, nachdem Sie damit fertig sind. Wie Sie damit umgehen, hängt natürlich davon ab, wie Sie den Timer erwarten. Auf diese Weise würde Ihr Timer vom aktuell festgelegten Intervall abweichen (ebenso wie das Stoppen und Neustarten). Ihr Mechanismus würde ermöglichen, dass jedes Intervall ausgelöst und behandelt wird, aber es kann zu einem Rückstand von nicht behandelten Ereignissen kommen, die jetzt behandelt werden, wo der Ablauf des Timers, der den Aufruf des Handlers verursacht hat, kurz bevorsteht.
timer.Interval = TimeSpan.FromSeconds(5).TotalMilliseconds;
timer.Elapsed += Timer_OnElapsed;
timer.AutoReset = false;
timer.Start();
public void Timer_OnElapsed(object sender, ElapsedEventArgs e)
{
if (!found)
{
found = LookForItWhichMightTakeALongTime();
}
timer.Start();
}
AutoReset und Elapsed sind für System.Threading.Timer, was nicht sicher für die UI-Arbeit ist. – Samuel
@Samuel - Elapsed ist das Ereignis, das vom OP verwendet wird. Vermutlich ist das keine WinForms App. – tvanfosson
Normalerweise stoppe ich den Timer während der Verarbeitung, gebe einen try/finally Block ein und setze den Timer wieder, wenn du fertig bist.
timer.enabled = false
oder
timer.stop();
und
timer.enabled = true
oder
timer.start();
Ich benutze die System.Threading.Timer wie so
class Class1
{
static Timer timer = new Timer(DoSomething,null,TimeSpan.FromMinutes(1),TimeSpan.FromMinutes(1));
private static void DoSomething(object state)
{
timer = null; // stop timer
// do some long stuff here
timer = new Timer(DoSomething, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
}
}
Sie sollten Timer-Instanzen immer abstellen, wenn Sie fertig sind. –
Der Timer wird weiterhin die Callback-Methode auslösen, solange der Garbage Collector nicht aufgeräumt hat.Dies kann zu unerwarteten, nicht deterministischen Effekten führen. –
Wenn LookForItWhichMightTakeALongTime()
eine lange Zeit in Anspruch nehmen wird, würde ich vorschlagen, keine System.Windows.Forms.Timer
verwenden, weil damit Ihren UI-Thread und der Benutzer sperren kann töten Ihre Anwendung zu denken, dass es gefroren ist.
Was Sie verwenden könnten, ist ein BackgroundWorker
(zusammen mit einem Timer
wenn gewünscht).
public class MyForm : Form
{
private BackgroundWorker backgroundWorker = new BackgroundWorker();
public MyForm()
{
InitializeComponents();
backgroundWorker.DoWork += backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted +=
backgroundWorker_RunWorkerCompleted;
backgroundWorker.RunWorkerAsync();
}
private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
e.Result = LookForItWhichMightTakeALongTime();
}
private void backgroundWorker_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
found = e.Result as MyClass;
}
}
Und Sie können Sie RunWorkerAsync()
von überall anrufen wollen, auch von einem Timer
wenn Sie möchten. Und stellen Sie sicher, zu überprüfen, ob die BackgroundWorker
bereits seit dem Aufruf RunWorkerAsync()
ausgeführt wird, wenn es eine Ausnahme auslöst.
private void timer_Tick(object sender, EventArgs e)
{
if (!backgroundWorker.IsBusy)
backgroundWorker.RunWorkerAsync();
}
- 1. Appium Fehler während der Verarbeitung des Befehls
- 2. Während der Verarbeitung ist ein Fehler aufgetreten.
- 3. Einmaliger Timer zum Speichern (SharedPreferences) der verstrichenen Zeit in Aktivität
- 4. ErrorIrresolvableConflict während des Erstellens eines Ereignisses
- 5. ObservableCollection kann während eines CollectionChanged-Ereignisses nicht geändert werden.
- 6. Verarbeiten, während ein Timer läuft
- 7. Wie man das gleiche Signal während der Verarbeitung eines Signals blockiert?
- 8. während der Verarbeitung laden Bild
- 9. Wie extrahiere ich EXTRA_PARAMETER-Daten während des PARAMETER_RECEIVED-Ereignisses?
- 10. Ermitteln, ob während des Mousedown-Ereignisses die Umschalttaste gedrückt wird
- 11. Wenn ein Thread, der SetWaitableTimer aufruft, beendet wird, während ein anderer Thread auf dem Timer wartet, wird der Timer abgebrochen?
- 12. Wie kann ein lauffähiger Timer unter bestimmten Bedingungen gestoppt werden?
- 13. Cassandra: Aufgrund eines Fehlers während der Verarbeitung des Commit-Protokolls während der Initialisierung beendet
- 14. apachemq Ausnahme während der JMS-Verarbeitung
- 15. Kann der Paketname während des Builds dynamisch angegeben werden?
- 16. Kann ein Service-Mitarbeiter dank eines Push-Ereignisses aktualisiert werden?
- 17. Responsive GUI während der Verarbeitung aktivieren
- 18. Wie kann der Timer im Ausgabebild angezeigt werden?
- 19. Während des Downloads einer Datei sind alle Anfragen blockiert
- 20. Wie kann ich feststellen, ob ein MySQL-Prozess blockiert ist?
- 21. C# - Blockieren eines Ordners vor der Änderung während der Verarbeitung
- 22. Wie kann das fokussierte Element in einem ListView während eines DragDrop-Ereignisses geändert werden?
- 23. Wie kann die Build-Umgebung während des Produktlebenszyklus erhalten werden?
- 24. Wie kann die Bildschirmausrichtung während des automatisierten Tests geändert werden?
- 25. Silverlight: MouseLeftButtonDown Timer zum wiederholten Auslösen eines Ereignisses
- 26. Ermitteln der Assemblyversion während eines Post-Build-Ereignisses
- 27. C#: Variable ändert Wert während der Verarbeitung
- 28. Wie kann ein Google Desktop-Gadget seine Benutzeroberfläche aktualisieren (Benutzereingaben verarbeiten), während der zugrunde liegende Code belegt/blockiert ist?
- 29. Kann ein globaler Timer im Hintergrund ausgeführt werden?
- 30. Shell-Skript zur Berechnung der verstrichenen Zeit
Dies sollte kein Community-Wiki gewesen sein. – Samuel
@ Samuel - jede Frage kann Gemeinschaft Wiki sein, wenn das Plakat wünscht. Die FAQ gibt nur an, dass einige Fragen von Anfang an Community-Wiki sein sollten, schränkt jedoch nicht die Anwendung von CW auf eine Frage ein. – tvanfosson
@tvanfosson: Ich habe ihn wissen lassen, dass Fragen wie diese nicht Community-Wiki sein sollten. – Samuel