Создать таймер в потоке - C#
Формулировка задачи:
У меня есть событие, оно вызывается безусловно в конце очереди других событий.
Проблема в том, что мне нужно чтобы событие вызывалось один раз в конце всех очередей.
Хочу добавить нечто вроде таймера в отдельном потоке, чтобы при обращении к нему из другого потока до истечения времени таймер начинал отсчёт заново, а по истечению времени событие выполнялось. Однако не совсем понимаю как подобное организовать.
Заранее спасибо.
Решение задачи: «Создать таймер в потоке»
textual
Листинг программы
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Bill77 { public class WatchDog : IDisposable { public WatchDog(TimeSpan timeoutInterval) { this.TimeOutInterval = timeoutInterval; this.mMonitorTask = null; this.mCancellationToken = null; this.mSignalEvent = new ManualResetEventSlim(); this.Start(); } public void Dispose() { this.Stop(); } public TimeSpan TimeOutInterval { get; set; } public event EventHandler TimeIsOut; public event EventHandler<RemaningTimeChangedEventArgs> TimeChanged; private Task mMonitorTask; private CancellationTokenSource mCancellationToken; private ManualResetEventSlim mSignalEvent; private void Start() { this.mCancellationToken = new CancellationTokenSource(); this.mMonitorTask = Task.Factory.StartNew(this.Monitor, this.mCancellationToken.Token, this.mCancellationToken.Token); } private void Stop() { if (this.mCancellationToken != null) { try { this.mCancellationToken.Cancel(); this.mMonitorTask.Wait(); } catch (AggregateException exc) { if (this.mMonitorTask.IsCanceled) { } } catch (Exception exc) { } finally { this.mCancellationToken.Dispose(); this.mMonitorTask.Dispose(); } } } public void Signal() { this.mSignalEvent.Set(); } private void Monitor(object ct) { CancellationToken token = (CancellationToken)ct; DateTime? lastSignalTime = null; while (true) { token.ThrowIfCancellationRequested(); if (this.mSignalEvent.Wait(100, token)) { this.mSignalEvent.Reset(); lastSignalTime = DateTime.Now; } if (lastSignalTime.HasValue) { if (lastSignalTime.Value.Add(this.TimeOutInterval) < DateTime.Now) { this.TimeIsOut?.Invoke(this, EventArgs.Empty); lastSignalTime = null; } else { TimeSpan remaining = lastSignalTime.Value.Add(this.TimeOutInterval).Subtract(DateTime.Now); this.TimeChanged?.Invoke(this, new RemaningTimeChangedEventArgs(remaining)); } } } } public class RemaningTimeChangedEventArgs : EventArgs { public RemaningTimeChangedEventArgs(TimeSpan remainingTime) { this.RemainingTime = remainingTime; } public TimeSpan RemainingTime { get; private set; } } } }
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д