annotate Implab/Components/RunnableComponent.cs @ 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.
author cin
date Mon, 29 Aug 2016 23:15:51 +0300
parents dd4a3590f9c6
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