Mercurial > pub > ImplabNet
comparison Implab/AbstractPromise.cs @ 138:f75cfa58e3d4 v2
added ICancellable.Cancel(Exception) to allow specify the reason of cancellation
author | cin |
---|---|
date | Tue, 17 Feb 2015 18:16:26 +0300 |
parents | 671f60cd0250 |
children | 16f926ee499d |
comparison
equal
deleted
inserted
replaced
137:238e15580926 | 138:f75cfa58e3d4 |
---|---|
66 /// </remarks> | 66 /// </remarks> |
67 /// <param name="error">Исключение возникшее при выполнении операции</param> | 67 /// <param name="error">Исключение возникшее при выполнении операции</param> |
68 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> | 68 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> |
69 protected void SetError(Exception error) { | 69 protected void SetError(Exception error) { |
70 if (BeginTransit()) { | 70 if (BeginTransit()) { |
71 m_error = error is PromiseTransientException ? error.InnerException : error; | 71 if (error is OperationCanceledException) { |
72 CompleteTransit(REJECTED_STATE); | 72 CompleteTransit(CANCELLED_STATE); |
73 OnError(); | 73 m_error = error.InnerException; |
74 OnCancelled(); | |
75 } else { | |
76 m_error = error is PromiseTransientException ? error.InnerException : error; | |
77 CompleteTransit(REJECTED_STATE); | |
78 OnError(); | |
79 } | |
74 } else { | 80 } else { |
75 WaitTransition(); | 81 WaitTransition(); |
76 if (m_state == SUCCEEDED_STATE) | 82 if (m_state == SUCCEEDED_STATE) |
77 throw new InvalidOperationException("The promise is already resolved"); | 83 throw new InvalidOperationException("The promise is already resolved"); |
78 } | 84 } |
80 | 86 |
81 /// <summary> | 87 /// <summary> |
82 /// Отменяет операцию, если это возможно. | 88 /// Отменяет операцию, если это возможно. |
83 /// </summary> | 89 /// </summary> |
84 /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks> | 90 /// <remarks>Для определения была ли операция отменена следует использовать свойство <see cref="IsCancelled"/>.</remarks> |
85 protected void SetCancelled() { | 91 protected void SetCancelled(Exception reason) { |
86 if (BeginTransit()) { | 92 if (BeginTransit()) { |
93 m_error = reason; | |
87 CompleteTransit(CANCELLED_STATE); | 94 CompleteTransit(CANCELLED_STATE); |
88 OnCancelled(); | 95 OnCancelled(); |
89 } | 96 } |
90 } | 97 } |
91 | 98 |
92 protected abstract void SignalSuccess(THandler handler); | 99 protected abstract void SignalSuccess(THandler handler); |
93 | 100 |
94 protected abstract void SignalError(THandler handler, Exception error); | 101 protected abstract void SignalError(THandler handler, Exception error); |
95 | 102 |
96 protected abstract void SignalCancelled(THandler handler); | 103 protected abstract void SignalCancelled(THandler handler, Exception reason); |
97 | 104 |
98 void OnSuccess() { | 105 void OnSuccess() { |
99 var hp = m_handlerPointer; | 106 var hp = m_handlerPointer; |
100 var slot = hp +1 ; | 107 var slot = hp +1 ; |
101 while (slot < m_handlersCommited) { | 108 while (slot < m_handlersCommited) { |
135 void OnCancelled() { | 142 void OnCancelled() { |
136 var hp = m_handlerPointer; | 143 var hp = m_handlerPointer; |
137 var slot = hp +1 ; | 144 var slot = hp +1 ; |
138 while (slot < m_handlersCommited) { | 145 while (slot < m_handlersCommited) { |
139 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { | 146 if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { |
140 SignalCancelled(m_handlers[slot]); | 147 SignalCancelled(m_handlers[slot], m_error); |
141 } | 148 } |
142 hp = m_handlerPointer; | 149 hp = m_handlerPointer; |
143 slot = hp +1 ; | 150 slot = hp +1 ; |
144 } | 151 } |
145 | 152 |
146 if (m_extraHandlers != null) { | 153 if (m_extraHandlers != null) { |
147 THandler handler; | 154 THandler handler; |
148 while (m_extraHandlers.TryDequeue(out handler)) | 155 while (m_extraHandlers.TryDequeue(out handler)) |
149 SignalCancelled(handler); | 156 SignalCancelled(handler, m_error); |
150 } | 157 } |
151 } | 158 } |
152 | 159 |
153 #endregion | 160 #endregion |
154 | 161 |
239 switch (m_state) { | 246 switch (m_state) { |
240 case SUCCEEDED_STATE: | 247 case SUCCEEDED_STATE: |
241 SignalSuccess(handler); | 248 SignalSuccess(handler); |
242 break; | 249 break; |
243 case CANCELLED_STATE: | 250 case CANCELLED_STATE: |
244 SignalCancelled(handler); | 251 SignalCancelled(handler, m_error); |
245 break; | 252 break; |
246 case REJECTED_STATE: | 253 case REJECTED_STATE: |
247 SignalError(handler, m_error); | 254 SignalError(handler, m_error); |
248 break; | 255 break; |
249 default: | 256 default: |
280 #endregion | 287 #endregion |
281 | 288 |
282 #region ICancellable implementation | 289 #region ICancellable implementation |
283 | 290 |
284 public void Cancel() { | 291 public void Cancel() { |
285 SetCancelled(); | 292 SetCancelled(null); |
286 } | 293 } |
287 | 294 |
288 #endregion | 295 public void Cancel(Exception reason) { |
296 SetCancelled(reason); | |
297 } | |
298 | |
299 #endregion | |
300 | |
301 public Exception Error { | |
302 get { | |
303 return m_error; | |
304 } | |
305 } | |
289 } | 306 } |
290 } | 307 } |
291 | 308 |