diff Implab/Components/PollingComponent.cs @ 258:d0876436d95d v3

missing file
author cin
date Fri, 13 Apr 2018 00:44:57 +0300
parents
children 7d52dc684bbd
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab/Components/PollingComponent.cs	Fri Apr 13 00:44:57 2018 +0300
@@ -0,0 +1,73 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Implab.Components {
+    public abstract class PollingComponent : RunnableComponent {
+
+        readonly Timer m_timer;
+
+        readonly CancellationTokenSource m_cancellation = new CancellationTokenSource();
+
+        /// <summary>
+        /// Poll interval in milliseconds.
+        /// </summary>
+        /// <returns></returns>
+        public int Interval { get; set; }
+
+        /// <summary>
+        /// Delay to the first poll after start in milliseconds
+        /// </summary>
+        /// <returns></returns>
+        public int Delay { get; set; }
+
+        /// <summary>
+        /// Indicates how to handle unhandled exceptions in <see cref="Poll()"/> method.
+        /// </summary>
+        /// <returns></returns>
+        public bool FailOnError { get; set; }
+
+        /// <summary>
+        /// Event for the unhandled exceptions in <see cref="Poll()"/> method.
+        /// </summary>
+        public event EventHandler<UnhandledExceptionEventArgs> UnhandledException;
+
+        protected PollingComponent(bool initialized) : base(initialized) {
+            m_timer = new Timer(OnTimer);
+        }
+
+        protected override void RunInternal() {
+            ScheduleNextPoll(Delay);
+        }
+
+
+        //TODO override stop
+        
+        protected abstract Task Poll(CancellationToken ct);
+
+        void ScheduleNextPoll(int timeout) {
+            lock (SynchronizationObject) {
+                if (State == ExecutionState.Running)
+                    m_timer.Change(timeout, Timeout.Infinite);
+            }
+        }
+
+        void OnTimer(object state) {
+            try {
+                Poll(m_cancellation.Token);
+            } catch (Exception e) {
+                UnhandledException.DispatchEvent(this, new UnhandledExceptionEventArgs(e, false));
+                if (FailOnError)
+                    Fail(e);
+            }
+            ScheduleNextPoll(Interval);
+        }
+
+        protected override void Dispose(bool disposing) {
+            if (disposing)
+                Safe.Dispose(m_timer, m_cancellation);
+            base.Dispose(disposing);
+        }
+
+    }
+}
\ No newline at end of file