# HG changeset patch
# User cin
# Date 2018-04-12 21:44:57
# Node ID d0876436d95d0318b469516774fbab5d39e05c0b
# Parent 440801d88019428b34a8ca73003b3028b9f247c5
missing file
diff --git a/Implab/Components/PollingComponent.cs b/Implab/Components/PollingComponent.cs
new file mode 100644
--- /dev/null
+++ b/Implab/Components/PollingComponent.cs
@@ -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();
+
+ ///
+ /// Poll interval in milliseconds.
+ ///
+ ///
+ public int Interval { get; set; }
+
+ ///
+ /// Delay to the first poll after start in milliseconds
+ ///
+ ///
+ public int Delay { get; set; }
+
+ ///
+ /// Indicates how to handle unhandled exceptions in method.
+ ///
+ ///
+ public bool FailOnError { get; set; }
+
+ ///
+ /// Event for the unhandled exceptions in method.
+ ///
+ public event EventHandler 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