annotate Implab/Components/RunnableComponent.cs @ 256:c52691faaf21 v3

Removed obsolete App, ComponentContainer Extracted IAsyncComponent interface Working on RunnableComponent
author cin
date Wed, 11 Apr 2018 03:05:14 +0300
parents 6f4630d0bcd9
children 440801d88019
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>
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
15 public class RunnableComponent : IAsyncComponent, IRunnable, IInitializable, IDisposable {
251
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
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
83 // processing calls from a client and internal processes.
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
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
91 // AsyncOperationDscriptor aggregates a task and it's cancellation token
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
92 AsyncOperationDescriptor m_current = AsyncOperationDescriptor.None;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
93
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
94 ExecutionState m_state;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
95
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
96
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
97 protected RunnableComponent(bool initialized) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
98 State = initialized ? ExecutionState.Ready : ExecutionState.Created;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
99 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
100
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
101 public Task Completion {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
102 get { return m_current.Task; }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
103 }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
104
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
105 public ExecutionState State {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
106 get { return m_state; }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
107 private set {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
108 if (m_state != value) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
109 m_state = value;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
110 StateChanged.DispatchEvent(this, new StateChangeEventArgs {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
111 State = value,
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
112 LastError = LastError
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
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
118 public Exception LastError { get; private set; }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
119
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
120 public event EventHandler<StateChangeEventArgs> StateChanged;
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
121
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
122 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
123 /// Releases all resources used by the current component regardless of its
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
124 /// execution state.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
125 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
126 /// <remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
127 /// Calling to this method may result unexpedted results if the component
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
128 /// isn't in the stopped state. Call this method after the component is
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
129 /// stopped if needed or if the component is in the failed state.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
130 /// </remarks>
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
131 public void Dispose() {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
132 bool dispose = false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
133 if (dispose) {
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
134 Dispose(true);
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
135 GC.SuppressFinalize(this);
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
136 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
137 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
138
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
139 ~RunnableComponent() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
140 Dispose(false);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
141 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
142
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
143 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
144 /// Releases all resources used by the current component regardless of its
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
145 /// execution state.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
146 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
147 /// <param name="disposing">Indicates that the component is disposed
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
148 /// during a normal disposing or during GC.</param>
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
149 protected virtual void Dispose(bool disposing) {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
150 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
151
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
152 public void Initialize() {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
153 var cookie = new object();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
154 if (MoveInitialize(cookie))
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
155 ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie);
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
156 else
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
157 throw new InvalidOperationException();
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
158 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
159
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
160 /// <summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
161 /// This method is used for initialization during a component creation.
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
162 /// </summary>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
163 /// <param name="ct">A cancellation token for this operation</param>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
164 /// <remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
165 /// This method should be used for short and mostly syncronous operations,
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
166 /// other operations which require time to run shoud be placed in
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
167 /// <see cref="StartInternalAsync(CancellationToken)"/> method.
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
168 /// </remarks>
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
169 protected virtual Task InitializeInternalAsync(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
170 return Task.CompletedTask;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
171 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
172
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
173 public void Start(CancellationToken ct) {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
174 var cookie = new object();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
175 if (MoveStart(cookie))
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
176 ScheduleTask(StartInternalAsync, ct, cookie);
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
177 else
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
178 throw new InvalidOperationException();
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
179 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
180
252
6f4630d0bcd9 removed absolete Diagnostics classes
cin
parents: 251
diff changeset
181 protected virtual Task StartInternalAsync(CancellationToken ct) {
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
182 return Task.CompletedTask;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
183 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
184
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
185 public void Stop(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
186 var cookie = new object();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
187 if (MoveStop(cookie))
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
188 ScheduleTask(StopAsync, ct, cookie);
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
189 else
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
190 throw new InvalidOperationException();
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
191 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
192
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
193 async Task StopAsync(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
194 m_current.Cancel();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
195 await Completion;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
196
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
197 ct.ThrowIfCancellationRequested();
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
198
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
199 await StopInternalAsync(ct);
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
200 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
201
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
202 protected virtual Task StopInternalAsync(CancellationToken ct) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
203 return Task.CompletedTask;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
204 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
205
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
206 protected void Fail(Exception err) {
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
207 lock(m_lock) {
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
208 if (m_state != ExecutionState.Running)
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
209 return;
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
210 m_cookie = new object();
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
211 LastError = err;
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
212 State = ExecutionState.Failed;
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
213 }
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
214 }
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
215
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
216
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
217 #region state management
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
218
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
219 bool MoveInitialize(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
220 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
221 if (State != ExecutionState.Created)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
222 return false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
223 State = ExecutionState.Initializing;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
224 m_cookie = cookie;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
225 return true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
226 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
227 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
228
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
229 bool MoveStart(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
230 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
231 if (State != ExecutionState.Ready)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
232 return false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
233 State = ExecutionState.Starting;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
234 m_cookie = cookie;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
235 return true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
236 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
237 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
238
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
239 bool MoveStop(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
240 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
241 if (State != ExecutionState.Starting && State != ExecutionState.Running)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
242 return false;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
243 State = ExecutionState.Stopping;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
244 m_cookie = cookie;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
245 return true;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
246 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
247 }
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
248
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
249 void MoveSuccess(object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
250 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
251 if (m_cookie != cookie)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
252 return;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
253 switch (State) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
254 case ExecutionState.Initializing:
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
255 State = ExecutionState.Ready;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
256 break;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
257 case ExecutionState.Starting:
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
258 State = ExecutionState.Running;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
259 break;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
260 case ExecutionState.Stopping:
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
261 State = ExecutionState.Stopped;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
262 break;
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
263 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
264 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
265 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
266
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
267 void MoveFailed(Exception err, object cookie) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
268 lock (m_lock) {
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
269 if (m_cookie != cookie)
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
270 return;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
271 LastError = err;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
272 State = ExecutionState.Failed;
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
273 }
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
274 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
275
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
276 void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) {
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
277
256
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
278 m_current = AsyncOperationDescriptor.Create(async (x) => {
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
279 try {
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
280 await next(x);
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
281 MoveSuccess(cookie);
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
282 } catch (Exception e) {
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
283 MoveFailed(e, cookie);
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
284 }
c52691faaf21 Removed obsolete App, ComponentContainer
cin
parents: 252
diff changeset
285 }, ct);
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
286 }
251
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
287
7c7e9ad6fe4a Prerelease version of RunnableComponent
cin
parents: 250
diff changeset
288 #endregion
250
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
289 }
9f63dade3a40 Working on runnable component
cin
parents:
diff changeset
290 }