annotate Implab/Components/RunnableComponent.cs @ 222:98eeb63cedb2

sync
author cin
date Tue, 22 Aug 2017 09:34:47 +0300
parents 40d7fed4a09e
children 2651cb9a4250
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
1 using System;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
2
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
3 namespace Implab.Components {
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
4 public abstract class RunnableComponent : IDisposable, IRunnable, IInitializable {
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
5 enum Commands {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
6 Ok = 0,
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
7 Fail,
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
8 Init,
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
9 Start,
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
10 Stop,
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
11 Dispose,
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
12 Last = Dispose
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
13 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
14
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
15 class StateMachine {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
16 static readonly ExecutionState[,] _transitions;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
17
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
18 static StateMachine() {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
19 _transitions = new ExecutionState[(int)ExecutionState.Last + 1, (int)Commands.Last + 1];
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
20
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
21 Edge(ExecutionState.Created, ExecutionState.Initializing, Commands.Init);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
22 Edge(ExecutionState.Created, ExecutionState.Disposed, Commands.Dispose);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
23
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
24 Edge(ExecutionState.Initializing, ExecutionState.Ready, Commands.Ok);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
25 Edge(ExecutionState.Initializing, ExecutionState.Failed, Commands.Fail);
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
26
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
27 Edge(ExecutionState.Ready, ExecutionState.Starting, Commands.Start);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
28 Edge(ExecutionState.Ready, ExecutionState.Disposed, Commands.Dispose);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
29
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
30 Edge(ExecutionState.Starting, ExecutionState.Running, Commands.Ok);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
31 Edge(ExecutionState.Starting, ExecutionState.Failed, Commands.Fail);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
32 Edge(ExecutionState.Starting, ExecutionState.Stopping, Commands.Stop);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
33 Edge(ExecutionState.Starting, ExecutionState.Disposed, Commands.Dispose);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
34
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
35 Edge(ExecutionState.Running, ExecutionState.Failed, Commands.Fail);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
36 Edge(ExecutionState.Running, ExecutionState.Stopping, Commands.Stop);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
37 Edge(ExecutionState.Running, ExecutionState.Disposed, Commands.Dispose);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
38
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
39 Edge(ExecutionState.Stopping, ExecutionState.Failed, Commands.Fail);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
40 Edge(ExecutionState.Stopping, ExecutionState.Disposed, Commands.Ok);
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
41
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
42 Edge(ExecutionState.Failed, ExecutionState.Disposed, Commands.Dispose);
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
43 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
44
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
45 static void Edge(ExecutionState s1, ExecutionState s2, Commands cmd) {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
46 _transitions[(int)s1, (int)cmd] = s2;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
47 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
48
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
49 public ExecutionState State {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
50 get;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
51 private set;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
52 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
53
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
54 public StateMachine(ExecutionState initial) {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
55 State = initial;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
56 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
57
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
58 public bool Move(Commands cmd) {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
59 var next = _transitions[(int)State, (int)cmd];
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
60 if (next == ExecutionState.Undefined)
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
61 return false;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
62 State = next;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
63 return true;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
64 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
65 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
66
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
67 IPromise m_pending;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
68 Exception m_lastError;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
69
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
70 readonly StateMachine m_stateMachine;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
71
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
72 protected RunnableComponent(bool initialized) {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
73 m_stateMachine = new StateMachine(initialized ? ExecutionState.Ready : ExecutionState.Created);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
74 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
75
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
76 protected virtual int DisposeTimeout {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
77 get {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
78 return 10000;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
79 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
80 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
81
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
82 void ThrowInvalidCommand(Commands cmd) {
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
83 if (m_stateMachine.State == ExecutionState.Disposed)
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
84 throw new ObjectDisposedException(ToString());
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
85
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
86 throw new InvalidOperationException(String.Format("Commnd {0} is not allowed in the state {1}", cmd, m_stateMachine.State));
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
87 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
88
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
89 void Move(Commands cmd) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
90 if (!m_stateMachine.Move(cmd))
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
91 ThrowInvalidCommand(cmd);
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
92 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
93
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
94 void Invoke(Commands cmd, Action action) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
95 lock (m_stateMachine)
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
96 Move(cmd);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
97
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
98 try {
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
99 action();
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
100 lock(m_stateMachine)
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
101 Move(Commands.Ok);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
102
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
103 } catch (Exception err) {
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
104 lock (m_stateMachine) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
105 Move(Commands.Fail);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
106 m_lastError = err;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
107 }
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
108 throw;
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
109 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
110 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
111
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
112 IPromise InvokeAsync(Commands cmd, Func<IPromise> action, Action<IPromise, IDeferred> chain) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
113 IPromise promise = null;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
114 IPromise prev;
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
115
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
116 var task = new ActionChainTask(action, null, null, true);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
117
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
118 lock (m_stateMachine) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
119 Move(cmd);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
120
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
121 prev = m_pending;
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
122
196
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
123 Action<Exception> errorOrCancel = e => {
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
124 if (e == null)
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
125 e = new OperationCanceledException();
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
126
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
127 lock (m_stateMachine) {
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
128 if (m_pending == promise) {
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
129 Move(Commands.Fail);
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
130 m_pending = null;
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
131 m_lastError = e;
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
132 }
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
133 }
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
134 throw new PromiseTransientException(e);
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
135 };
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
136
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
137 promise = task.Then(
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
138 () => {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
139 lock(m_stateMachine) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
140 if (m_pending == promise) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
141 Move(Commands.Ok);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
142 m_pending = null;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
143 }
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
144 }
196
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
145 },
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
146 errorOrCancel,
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 187
diff changeset
147 errorOrCancel
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
148 );
157
cin
parents: 156
diff changeset
149
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
150 m_pending = promise;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
151 }
157
cin
parents: 156
diff changeset
152
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
153 if (prev == null)
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
154 task.Resolve();
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
155 else
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
156 chain(prev, task);
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
157
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
158 return promise;
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
159 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
160
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
161
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
162 #region IInitializable implementation
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
163
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
164 public void Init() {
184
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
165 Invoke(Commands.Init, OnInitialize);
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
166 }
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
167
d6a8cba73acc working on runnable component
cin
parents: 180
diff changeset
168 protected virtual void OnInitialize() {
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
169 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
170
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
171 #endregion
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
172
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
173 #region IRunnable implementation
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
174
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
175 public IPromise Start() {
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
176 return InvokeAsync(Commands.Start, OnStart, null);
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
177 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
178
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
179 protected virtual IPromise OnStart() {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
180 return Promise.SUCCESS;
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
181 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
182
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
183 public IPromise Stop() {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
184 return InvokeAsync(Commands.Stop, OnStop, StopPending).Then(Dispose);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
185 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
186
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
187 protected virtual IPromise OnStop() {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
188 return Promise.SUCCESS;
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
189 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
190
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
191 /// <summary>
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
192 /// Stops the current operation if one exists.
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
193 /// </summary>
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
194 /// <param name="current">Current.</param>
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
195 /// <param name="stop">Stop.</param>
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
196 protected virtual void StopPending(IPromise current, IDeferred stop) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
197 if (current == null) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
198 stop.Resolve();
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
199 } else {
187
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
200 // связваем текущую операцию с операцией остановки
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
201 current.On(
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
202 stop.Resolve, // если текущая операция заверщилась, то можно начинать остановку
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
203 stop.Reject, // если текущая операция дала ошибку - то все плохо, нельзя продолжать
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
204 e => stop.Resolve() // если текущая отменилась, то можно начинать остановку
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
205 );
dd4a3590f9c6 Reworked cancelation handling, if the cancel handler isn't specified the OperationCanceledException will be handled by the error handler
cin
parents: 186
diff changeset
206 // посылаем текущей операции сигнал остановки
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
207 current.Cancel();
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
208 }
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
209 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
210
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
211 public ExecutionState State {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
212 get {
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
213 return m_stateMachine.State;
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
214 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
215 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
216
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
217 public Exception LastError {
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
218 get {
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
219 return m_lastError;
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
220 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
221 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
222
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
223 #endregion
185
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
224
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
225 #region IDisposable implementation
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
226
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
227 public void Dispose() {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
228 IPromise pending;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
229 lock (m_stateMachine) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
230 if (m_stateMachine.State == ExecutionState.Disposed)
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
231 return;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
232
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
233 Move(Commands.Dispose);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
234
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
235 GC.SuppressFinalize(this);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
236
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
237 pending = m_pending;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
238 m_pending = null;
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
239 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
240 if (pending != null) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
241 pending.Cancel();
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
242 pending.Timeout(DisposeTimeout).On(
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
243 () => Dispose(true, null),
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
244 err => Dispose(true, err),
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
245 reason => Dispose(true, new OperationCanceledException("The operation is cancelled", reason))
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
246 );
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
247 } else {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
248 Dispose(true, m_lastError);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
249 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
250 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
251
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
252 ~RunnableComponent() {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
253 Dispose(false, null);
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
254 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
255
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
256 #endregion
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
257
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
258 protected virtual void Dispose(bool disposing, Exception lastError) {
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
259
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
260 }
822aab37b107 runnable component, work in progress
cin
parents: 184
diff changeset
261
156
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
262 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
263 }
97fbbf816844 Promises: SignalXXX methods merged into SignalHandler method.
cin
parents:
diff changeset
264