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 } |