Mercurial > pub > ImplabNet
comparison Implab/Components/PollingComponent.cs @ 259:7d52dc684bbd v3
PollingComponent: implemented correct stopping
| author | cin |
|---|---|
| date | Fri, 13 Apr 2018 03:57:39 +0300 |
| parents | d0876436d95d |
| children | 547a2fc0d93e |
comparison
equal
deleted
inserted
replaced
| 258:d0876436d95d | 259:7d52dc684bbd |
|---|---|
| 6 public abstract class PollingComponent : RunnableComponent { | 6 public abstract class PollingComponent : RunnableComponent { |
| 7 | 7 |
| 8 readonly Timer m_timer; | 8 readonly Timer m_timer; |
| 9 | 9 |
| 10 readonly CancellationTokenSource m_cancellation = new CancellationTokenSource(); | 10 readonly CancellationTokenSource m_cancellation = new CancellationTokenSource(); |
| 11 | |
| 12 Task m_pending; | |
| 13 Task m_poll; | |
| 11 | 14 |
| 12 /// <summary> | 15 /// <summary> |
| 13 /// Poll interval in milliseconds. | 16 /// Poll interval in milliseconds. |
| 14 /// </summary> | 17 /// </summary> |
| 15 /// <returns></returns> | 18 /// <returns></returns> |
| 39 protected override void RunInternal() { | 42 protected override void RunInternal() { |
| 40 ScheduleNextPoll(Delay); | 43 ScheduleNextPoll(Delay); |
| 41 } | 44 } |
| 42 | 45 |
| 43 | 46 |
| 44 //TODO override stop | 47 protected override async Task StopInternalAsync(CancellationToken ct) { |
| 48 // component in Stopping state, no new polls will be scheduled | |
| 49 m_cancellation.Cancel(); | |
| 50 try { | |
| 51 // await for pending poll | |
| 52 await m_poll; | |
| 53 } catch (OperationCanceledException e) { | |
| 54 // OK | |
| 55 } | |
| 56 } | |
| 45 | 57 |
| 46 protected abstract Task Poll(CancellationToken ct); | 58 protected abstract Task Poll(CancellationToken ct); |
| 47 | 59 |
| 48 void ScheduleNextPoll(int timeout) { | 60 void ScheduleNextPoll(int timeout) { |
| 49 lock (SynchronizationObject) { | 61 lock (SynchronizationObject) { |
| 50 if (State == ExecutionState.Running) | 62 if (State == ExecutionState.Running) { |
| 63 m_pending = Safe.CreateTask(m_cancellation.Token); | |
| 64 m_poll = m_pending.Then(() => Poll(m_cancellation.Token)); | |
| 51 m_timer.Change(timeout, Timeout.Infinite); | 65 m_timer.Change(timeout, Timeout.Infinite); |
| 66 } | |
| 52 } | 67 } |
| 53 } | 68 } |
| 54 | 69 |
| 55 void OnTimer(object state) { | 70 async void OnTimer(object state) { |
| 56 try { | 71 try { |
| 57 Poll(m_cancellation.Token); | 72 m_pending.Start(); |
| 73 await m_poll; | |
| 58 } catch (Exception e) { | 74 } catch (Exception e) { |
| 59 UnhandledException.DispatchEvent(this, new UnhandledExceptionEventArgs(e, false)); | 75 UnhandledException.DispatchEvent(this, new UnhandledExceptionEventArgs(e, false)); |
| 60 if (FailOnError) | 76 if (FailOnError) |
| 61 Fail(e); | 77 Fail(e); |
| 62 } | 78 } |
