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 }