annotate Implab/Components/RunnableComponent.cs @ 253:34df34841225 v3 v3.0.1-beta

Implab.Diagnostics drafts
author cin
date Mon, 12 Feb 2018 17:03:37 +0300
parents 6f4630d0bcd9
children c52691faaf21
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
1 using System;
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
2 using System.Diagnostics;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
3 using System.Threading;
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
4 using System.Threading.Tasks;
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
5
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
6 namespace Implab.Components {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
7 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
8 /// Base class for implementing components which support start and stop operations,
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
9 /// such components may represent running services.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
10 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
11 /// <remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
12 /// This class provides a basic lifecycle from the creation to the
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
13 /// termination of the component.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
14 /// </remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
15 public class RunnableComponent : IRunnable, IInitializable, IDisposable {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
16
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
17 /// <summary>
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
18 /// This class bounds <see cref="CancellationTokenSource"/> lifetime to the task,
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
19 /// when the task completes the associated token source will be disposed.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
20 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
21 class AsyncOperationDescriptor {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
22
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
23 public static AsyncOperationDescriptor None { get; } = new AsyncOperationDescriptor();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
24
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
25 readonly CancellationTokenSource m_cts;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
26
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
27 bool m_done;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
28
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
29 public CancellationToken Token {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
30 get { return m_cts == null ? CancellationToken.None : m_cts.Token; }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
31 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
32
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
33 public Task Task { get; private set; }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
34
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
35 private AsyncOperationDescriptor(Task task, CancellationTokenSource cts) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
36 m_cts = cts;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
37 Task = Chain(task);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
38 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
39
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
40 private AsyncOperationDescriptor() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
41 Task = Task.CompletedTask;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
42 }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
43
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
44 public void Cancel() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
45 if (m_cts != null) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
46 lock (m_cts) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
47 if (!m_done)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
48 m_cts.Cancel();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
49 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
50 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
51 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
52
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
53 void Done() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
54 if (m_cts != null) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
55 lock (m_cts) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
56 m_done = true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
57 m_cts.Dispose();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
58 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
59 } else {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
60 m_done = true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
61 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
62 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
63
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
64 async Task Chain(Task other) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
65 try {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
66 await other;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
67 } finally {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
68 Done();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
69 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
70 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
71
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
72 public static AsyncOperationDescriptor Create(Func<CancellationToken, Task> factory, CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
73 var cts = ct.CanBeCanceled ?
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
74 CancellationTokenSource.CreateLinkedTokenSource(ct) :
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
75 new CancellationTokenSource();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
76
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
77 return new AsyncOperationDescriptor(factory(cts.Token), cts);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
78 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
79
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
80 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
81
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
82 // this lock is used to synchronize state flow of the component during
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
83 // completions or the operations.
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
84 readonly object m_lock = new object();
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
85
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
86 // current operation cookie, used to check wheather a call to
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
87 // MoveSuccess/MoveFailed method belongs to the current
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
88 // operation, if cookies didn't match ignore completion result.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
89 object m_cookie;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
90
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
91 AsyncOperationDescriptor m_current = AsyncOperationDescriptor.None;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
92
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
93 ExecutionState m_state;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
94
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
95
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
96 protected RunnableComponent(bool initialized) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
97 State = initialized ? ExecutionState.Ready : ExecutionState.Created;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
98 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
99
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
100 public Task Completion {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
101 get { return m_current.Task; }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
102 }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
103
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
104 public ExecutionState State {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
105 get { return m_state; }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
106 private set {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
107 if (m_state != value) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
108 m_state = value;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
109 StateChanged.DispatchEvent(this, new StateChangeEventArgs {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
110 State = value,
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
111 LastError = LastError
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
112 });
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
113 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
114 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
115 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
116
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
117 public Exception LastError { get; private set; }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
118
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
119 public event EventHandler<StateChangeEventArgs> StateChanged;
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
120
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
121 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
122 /// Releases all resources used by the current component regardless of its
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
123 /// execution state.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
124 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
125 /// <remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
126 /// Calling to this method may result unexpedted results if the component
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
127 /// isn't in the stopped state. Call this method after the component is
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
128 /// stopped if needed or if the component is in the failed state.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
129 /// </remarks>
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
130 public void Dispose() {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
131 bool dispose = false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
132 if (dispose) {
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
133 Dispose(true);
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
134 GC.SuppressFinalize(this);
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
135 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
136 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
137
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
138 ~RunnableComponent() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
139 Dispose(false);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
140 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
141
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
142 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
143 /// Releases all resources used by the current component regardless of its
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
144 /// execution state.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
145 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
146 /// <param name="disposing">Indicates that the component is disposed
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
147 /// during a normal disposing or during GC.</param>
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
148 protected virtual void Dispose(bool disposing) {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
149 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
150
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
151 public void Initialize() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
152 var cookie = new object();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
153 if (MoveInitialize(cookie))
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
154 ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
155 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
156
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
157 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
158 /// This method is used for initialization during a component creation.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
159 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
160 /// <param name="ct">A cancellation token for this operation</param>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
161 /// <remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
162 /// This method should be used for short and mostly syncronous operations,
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
163 /// other operations which require time to run shoud be placed in
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
164 /// <see cref="StartInternalAsync(CancellationToken)"/> method.
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
165 /// </remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
166 protected virtual Task InitializeInternalAsync(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
167 return Task.CompletedTask;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
168 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
169
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
170 public void Start(CancellationToken ct) {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
171 var cookie = new object();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
172 if (MoveStart(cookie))
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
173 ScheduleTask(StartInternalAsync, ct, cookie);
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
174 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
175
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
176 protected virtual Task StartInternalAsync(CancellationToken ct) {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
177 return Task.CompletedTask;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
178 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
179
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
180 public void Stop(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
181 var cookie = new object();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
182 if (MoveStop(cookie))
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
183 ScheduleTask(StopAsync, ct, cookie);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
184 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
185
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
186 async Task StopAsync(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
187 m_current.Cancel();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
188 await Completion;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
189
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
190 ct.ThrowIfCancellationRequested();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
191
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
192 await StopInternalAsync(ct);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
193 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
194
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
195 protected virtual Task StopInternalAsync(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
196 return Task.CompletedTask;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
197 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
198
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
199
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
200 #region state management
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
201
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
202 bool MoveInitialize(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
203 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
204 if (State != ExecutionState.Created)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
205 return false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
206 State = ExecutionState.Initializing;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
207 m_cookie = cookie;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
208 return true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
209 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
210 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
211
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
212 bool MoveStart(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
213 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
214 if (State != ExecutionState.Ready)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
215 return false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
216 State = ExecutionState.Starting;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
217 m_cookie = cookie;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
218 return true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
219 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
220 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
221
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
222 bool MoveStop(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
223 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
224 if (State != ExecutionState.Starting && State != ExecutionState.Running)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
225 return false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
226 State = ExecutionState.Stopping;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
227 m_cookie = cookie;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
228 return true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
229 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
230 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
231
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
232 void MoveSuccess(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
233 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
234 if (m_cookie != cookie)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
235 return;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
236 switch (State) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
237 case ExecutionState.Initializing:
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
238 State = ExecutionState.Ready;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
239 break;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
240 case ExecutionState.Starting:
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
241 State = ExecutionState.Running;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
242 break;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
243 case ExecutionState.Stopping:
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
244 State = ExecutionState.Stopped;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
245 break;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
246 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
247 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
248 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
249
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
250 void MoveFailed(Exception err, object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
251 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
252 if (m_cookie != cookie)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
253 return;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
254 LastError = err;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
255 State = ExecutionState.Failed;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
256 }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
257 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
258
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
259
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
260
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
261 protected async void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
262 try {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
263 m_current = AsyncOperationDescriptor.Create(next, ct);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
264 await m_current.Task;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
265 MoveSuccess(cookie);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
266 } catch (Exception e) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
267 MoveFailed(e, cookie);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
268 }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
269 }
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
270
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
271 #endregion
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
272 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
273 }