comparison Implab/FuncChainTaskBase.cs @ 149:eb793fbbe4ea v2

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