comparison Implab/ActionChainTaskBase.cs @ 149:eb793fbbe4ea v2

fixed promises cancellation
author cin
date Wed, 06 May 2015 17:11:27 +0300
parents 706fccb85524
children 75103928da09
comparison
equal deleted inserted replaced
148:e6d4b41f0101 149:eb793fbbe4ea
6 readonly Func<Exception, IPromise> m_error; 6 readonly Func<Exception, IPromise> m_error;
7 readonly Func<Exception, IPromise> m_cancel; 7 readonly Func<Exception, IPromise> m_cancel;
8 8
9 int m_cancelationLock; 9 int m_cancelationLock;
10 10
11 protected ActionChainTaskBase( Func<Exception, IPromise> error, Func<Exception, IPromise> cancel) { 11 protected ActionChainTaskBase(Func<Exception, IPromise> error, Func<Exception, IPromise> cancel, bool autoCancellable) {
12 m_error = error; 12 m_error = error;
13 m_cancel = cancel; 13 m_cancel = cancel;
14 if (autoCancellable)
15 CancellationRequested(CancelOperation);
14 } 16 }
15 17
16 public void Reject(Exception error) { 18 public void Reject(Exception error) {
17 if (LockCancelation()) 19 if (LockCancelation())
18 HandleErrorInternal(error); 20 HandleErrorInternal(error);
19 } 21 }
20 22
21 23
22 24
23 public override void CancelOperation(Exception reason) { 25 public override void CancelOperation(Exception reason) {
24 if (m_cancel != null && LockCancelation()) { 26 if (LockCancelation()) {
25 try { 27 if (m_cancel != null) {
26 Observe(m_cancel(reason)); 28 try {
27 } catch(Exception err) { 29 m_cancel(reason).On(SetResult, SetError, SetCancelled);
28 HandleErrorInternal(err); 30 } catch (Exception err) {
31 HandleErrorInternal(err);
32 }
33 } else {
34 SetCancelled(reason);
29 } 35 }
30 } 36 }
31
32 } 37 }
33 38
34 protected void HandleErrorInternal(Exception error) { 39 protected void HandleErrorInternal(Exception error) {
35 if (m_error != null) { 40 if (m_error != null) {
36 try { 41 try {
37 Observe(m_error(error)); 42 var p = m_error(error);
38 } catch(Exception err) { 43 p.On(SetResult,SetError,SetCancelled);
44 CancellationRequested(p.Cancel);
45 } catch (Exception err) {
39 SetError(err); 46 SetError(err);
40 } 47 }
41 } else { 48 } else {
42 SetError(error); 49 SetError(error);
43 } 50 }
44 }
45
46 protected void Observe(IPromise operation) {
47 if (operation == null)
48 throw new NullReferenceException("The task returned null promise");
49
50 // pass operation results to the current promise
51 operation.On(SetResult, SetError, SetCancelled);
52
53 // pass the cancelation request
54 CancellationRequested(operation.Cancel);
55 } 51 }
56 52
57 protected bool LockCancelation() { 53 protected bool LockCancelation() {
58 return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0); 54 return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0);
59 } 55 }