| 144 | 1 using System; | 
|  | 2 using System.Threading; | 
|  | 3 | 
|  | 4 namespace Implab { | 
|  | 5     public class FuncTaskBase<TResult> : AbstractPromise<TResult> { | 
|  | 6         readonly Func<Exception, TResult> m_cancel; | 
|  | 7         readonly Func<Exception, TResult> m_error; | 
|  | 8 | 
|  | 9         int m_cancelationLock; | 
|  | 10 | 
| 149 | 11         protected FuncTaskBase( Func<Exception, TResult> error, Func<Exception, TResult> cancel, bool autoCancellable) { | 
| 144 | 12             m_error = error; | 
|  | 13             m_cancel = cancel; | 
| 149 | 14             if (autoCancellable) | 
|  | 15                 CancellationRequested(CancelOperation); | 
| 144 | 16         } | 
|  | 17 | 
|  | 18         public void Reject(Exception error) { | 
|  | 19             Safe.ArgumentNotNull(error, "error"); | 
|  | 20             if (LockCancelation()) | 
|  | 21                 HandleErrorInternal(error); | 
|  | 22         } | 
|  | 23 | 
|  | 24         protected void HandleErrorInternal(Exception error) { | 
|  | 25             if (m_error != null) { | 
|  | 26                 try { | 
|  | 27                     SetResult(m_error(error)); | 
|  | 28                 } catch(Exception err) { | 
|  | 29                     SetError(err); | 
|  | 30                 } | 
|  | 31             } else { | 
|  | 32                 SetError(error); | 
|  | 33             } | 
|  | 34         } | 
|  | 35 | 
|  | 36         public override void CancelOperation(Exception reason) { | 
|  | 37             if (LockCancelation()) { | 
|  | 38                 if (m_cancel != null) { | 
|  | 39                     try { | 
|  | 40                         SetResult(m_cancel(reason)); | 
|  | 41                     } catch (Exception err) { | 
|  | 42                         HandleErrorInternal(err); | 
|  | 43                     } | 
|  | 44                 } else { | 
|  | 45                     SetCancelled(reason); | 
|  | 46                 } | 
|  | 47             } | 
|  | 48         } | 
|  | 49 | 
|  | 50         protected bool LockCancelation() { | 
|  | 51             return 0 == Interlocked.CompareExchange(ref m_cancelationLock, 1, 0); | 
|  | 52         } | 
|  | 53     } | 
|  | 54 } | 
|  | 55 |