| @@ -0,0 +1,33 | |||
|  | 1 | using System; | |
|  | 2 | using System.Collections.Generic; | |
|  | 3 | using System.Linq; | |
|  | 4 | using System.Text; | |
|  | 5 | ||
|  | 6 | namespace Implab | |
|  | 7 | { | |
|  | 8 | public interface IPromise | |
|  | 9 | { | |
|  | 10 | /// <summary> | |
|  | 11 | /// Check whereather the promise has no more than one dependent promise. | |
|  | 12 | /// </summary> | |
|  | 13 | bool IsExclusive | |
|  | 14 | { | |
|  | 15 | get; | |
|  | 16 | } | |
|  | 17 | ||
|  | 18 | /// <summary> | |
|  | 19 | /// The current state of the promise. | |
|  | 20 | /// </summary> | |
|  | 21 | PromiseState State | |
|  | 22 | { | |
|  | 23 | get; | |
|  | 24 | } | |
|  | 25 | ||
|  | 26 | /// <summary> | |
|  | 27 | /// Tries to cancel the promise or the complete chain. | |
|  | 28 | /// </summary> | |
|  | 29 | /// <param name="dependencies">Try to cancel the parent promise is it has the only one child</param> | |
|  | 30 | /// <returns></returns> | |
|  | 31 | bool Cancel(bool dependencies); | |
|  | 32 | } | |
|  | 33 | } | |
| @@ -0,0 +1,36 | |||
|  | 1 | using System; | |
|  | 2 | using System.Collections.Generic; | |
|  | 3 | using System.Linq; | |
|  | 4 | using System.Text; | |
|  | 5 | ||
|  | 6 | namespace Implab | |
|  | 7 | { | |
|  | 8 | ||
|  | 9 | public class ProgressInitEventArgs: EventArgs | |
|  | 10 | { | |
|  | 11 | public float MaxProgress | |
|  | 12 | { | |
|  | 13 | get; | |
|  | 14 | private set; | |
|  | 15 | } | |
|  | 16 | ||
|  | 17 | public float CurrentProgress | |
|  | 18 | { | |
|  | 19 | get; | |
|  | 20 | private set; | |
|  | 21 | } | |
|  | 22 | ||
|  | 23 | public string Message | |
|  | 24 | { | |
|  | 25 | get; | |
|  | 26 | private set; | |
|  | 27 | } | |
|  | 28 | ||
|  | 29 | public ProgressInitEventArgs(float current, float max, string message) | |
|  | 30 | { | |
|  | 31 | this.MaxProgress = max; | |
|  | 32 | this.CurrentProgress = current; | |
|  | 33 | this.Message = message; | |
|  | 34 | } | |
|  | 35 | } | |
|  | 36 | } | |
| @@ -0,0 +1,15 | |||
|  | 1 | using System; | |
|  | 2 | using System.Collections.Generic; | |
|  | 3 | using System.Linq; | |
|  | 4 | using System.Text; | |
|  | 5 | ||
|  | 6 | namespace Implab | |
|  | 7 | { | |
|  | 8 | public enum PromiseState | |
|  | 9 | { | |
|  | 10 | Unresolved, | |
|  | 11 | Resolved, | |
|  | 12 | Cancelled, | |
|  | 13 | Rejected | |
|  | 14 | } | |
|  | 15 | } | |
| @@ -0,0 +1,113 | |||
|  | 1 | using System; | |
|  | 2 | using System.Collections.Generic; | |
|  | 3 | using System.Linq; | |
|  | 4 | using System.Text; | |
|  | 5 | using System.Threading; | |
|  | 6 | ||
|  | 7 | namespace Implab | |
|  | 8 | { | |
|  | 9 | /// <summary> | |
|  | 10 | /// This class allows to interact with asyncronuos task. | |
|  | 11 | /// </summary> | |
|  | 12 | /// <remarks> | |
|  | 13 | /// Members of this object are thread safe. | |
|  | 14 | /// </remarks> | |
|  | 15 | class TaskController | |
|  | 16 | { | |
|  | 17 | object m_lock; | |
|  | 18 | string m_message; | |
|  | 19 | bool m_cancelled; | |
|  | 20 | ||
|  | 21 | float m_current; | |
|  | 22 | float m_max; | |
|  | 23 | ||
|  | 24 | public event EventHandler<ValueEventArgs<string>> MessageUpdated; | |
|  | 25 | public event EventHandler<ValueEventArgs<float>> ProgressUpdated; | |
|  | 26 | public event EventHandler<ProgressInitEventArgs> ProgressInit; | |
|  | 27 | ||
|  | 28 | public TaskController() | |
|  | 29 | { | |
|  | 30 | m_lock = new Object(); | |
|  | 31 | } | |
|  | 32 | ||
|  | 33 | public string Message | |
|  | 34 | { | |
|  | 35 | get | |
|  | 36 | { | |
|  | 37 | lock (m_lock) | |
|  | 38 | return m_message; | |
|  | 39 | } | |
|  | 40 | set | |
|  | 41 | { | |
|  | 42 | lock (m_lock) | |
|  | 43 | { | |
|  | 44 | m_message = value; | |
|  | 45 | OnMessageUpdated(); | |
|  | 46 | } | |
|  | 47 | } | |
|  | 48 | } | |
|  | 49 | ||
|  | 50 | public float CurrentProgress | |
|  | 51 | { | |
|  | 52 | get | |
|  | 53 | { | |
|  | 54 | lock (m_lock) | |
|  | 55 | return m_current; | |
|  | 56 | } | |
|  | 57 | set | |
|  | 58 | { | |
|  | 59 | lock (m_lock) | |
|  | 60 | { | |
|  | 61 | var prev = m_current; | |
|  | 62 | m_current = value; | |
|  | 63 | if (m_current >= m_max) | |
|  | 64 | m_current = m_max; | |
|  | 65 | if (m_current != prev) | |
|  | 66 | OnProgressUpdated(); | |
|  | 67 | } | |
|  | 68 | } | |
|  | 69 | } | |
|  | 70 | ||
|  | 71 | public void InitProgress(float current, float max, string message) | |
|  | 72 | { | |
|  | 73 | if (max < 0) | |
|  | 74 | throw new ArgumentOutOfRangeException("max"); | |
|  | 75 | if (current < 0 || current > max) | |
|  | 76 | throw new ArgumentOutOfRangeException("current"); | |
|  | 77 | ||
|  | 78 | lock(m_lock) { | |
|  | 79 | m_current = current; | |
|  | 80 | m_max = max; | |
|  | 81 | m_message = message; | |
|  | 82 | OnProgressInit(); | |
|  | 83 | } | |
|  | 84 | } | |
|  | 85 | ||
|  | 86 | protected virtual void OnMessageUpdated() | |
|  | 87 | { | |
|  | 88 | var temp = MessageUpdated; | |
|  | 89 | if (temp != null) | |
|  | 90 | { | |
|  | 91 | temp(this, new ValueEventArgs<string>(m_message)); | |
|  | 92 | } | |
|  | 93 | } | |
|  | 94 | ||
|  | 95 | protected virtual void OnProgressUpdated() | |
|  | 96 | { | |
|  | 97 | var temp = ProgressUpdated; | |
|  | 98 | if (temp != null) | |
|  | 99 | { | |
|  | 100 | temp(this,new ValueEventArgs<float>(m_current)); | |
|  | 101 | } | |
|  | 102 | } | |
|  | 103 | ||
|  | 104 | protected virtual void OnProgressInit() | |
|  | 105 | { | |
|  | 106 | var temp = ProgressInit; | |
|  | 107 | if (temp != null) | |
|  | 108 | { | |
|  | 109 | temp(this, new ProgressInitEventArgs(m_current,m_max, m_message)); | |
|  | 110 | } | |
|  | 111 | } | |
|  | 112 | } | |
|  | 113 | } | |
| @@ -0,0 +1,20 | |||
|  | 1 | using System; | |
|  | 2 | using System.Collections.Generic; | |
|  | 3 | using System.Linq; | |
|  | 4 | using System.Text; | |
|  | 5 | ||
|  | 6 | namespace Implab | |
|  | 7 | { | |
|  | 8 | public class ValueEventArgs<T>: EventArgs | |
|  | 9 | { | |
|  | 10 | public ValueEventArgs(T value) | |
|  | 11 | { | |
|  | 12 | this.Value = value; | |
|  | 13 | } | |
|  | 14 | public T Value | |
|  | 15 | { | |
|  | 16 | get; | |
|  | 17 | private set; | |
|  | 18 | } | |
|  | 19 | } | |
|  | 20 | } | |
|  | 1 | NO CONTENT: modified file, binary diff hidden | 
| @@ -32,10 +32,14 | |||
|  | 32 | 32 | <Reference Include="System" /> | 
|  | 33 | 33 | </ItemGroup> | 
|  | 34 | 34 | <ItemGroup> | 
|  | 35 | <Compile Include="ICancellable.cs" /> | |
|  | 36 | <Compile Include="TaskController.cs" /> | |
|  | 37 | <Compile Include="ProgressInitEventArgs.cs" /> | |
|  | 35 | 38 | <Compile Include="Properties\AssemblyInfo.cs" /> | 
|  | 36 | 39 | <Compile Include="Promise.cs" /> | 
|  | 37 | 40 | <Compile Include="AsyncPool.cs" /> | 
|  | 38 | 41 | <Compile Include="Safe.cs" /> | 
|  | 42 | <Compile Include="ValueEventArgs.cs" /> | |
|  | 39 | 43 | </ItemGroup> | 
|  | 40 | 44 | <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> | 
|  | 41 | 45 | <ItemGroup> | 
| @@ -48,30 +48,32 namespace Implab { | |||
|  | 48 | 48 | /// только инициатор обещания иначе могут возникнуть противоречия. | 
|  | 49 | 49 | /// </para> | 
|  | 50 | 50 | /// </remarks> | 
|  | 51 | public class Promise<T> { | |
|  | 51 | public class Promise<T>: IPromise { | |
|  | 52 | 52 | |
|  | 53 | 53 | struct ResultHandlerInfo { | 
|  | 54 | 54 | public ResultHandler<T> resultHandler; | 
|  | 55 | 55 | public ErrorHandler errorHandler; | 
|  | 56 | } | |
|  | 57 | ||
|  | 58 | enum State { | |
|  | 59 | Unresolved, | |
|  | 60 | Resolving, | |
|  | 61 | Resolved, | |
|  | 62 | Cancelled | |
|  | 56 | public Action cancelHandler; | |
|  | 63 | 57 | } | 
|  | 64 | 58 | |
|  | 65 | 59 | LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>(); | 
|  | 66 | State m_state; | |
|  | 60 | PromiseState m_state; | |
|  | 67 | 61 | bool m_cancellable; | 
|  | 68 | 62 | T m_result; | 
|  | 69 | 63 | Exception m_error; | 
|  | 64 | IPromise m_parent; | |
|  | 65 | int m_childrenCount; | |
|  | 70 | 66 | |
|  | 71 | 67 | public Promise() { | 
|  | 72 | 68 | m_cancellable = true; | 
|  | 73 | 69 | } | 
|  | 74 | 70 | |
|  | 71 | public Promise(IPromise parent, bool cancellable) | |
|  | 72 | { | |
|  | 73 | m_cancellable = cancellable; | |
|  | 74 | m_parent = parent; | |
|  | 75 | } | |
|  | 76 | ||
|  | 75 | 77 | /// <summary> | 
|  | 76 | 78 | /// Событие, возникающее при отмене асинхронной операции. | 
|  | 77 | 79 | /// </summary> | 
| @@ -87,12 +89,12 namespace Implab { | |||
|  | 87 | 89 | /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> | 
|  | 88 | 90 | public void Resolve(T result) { | 
|  | 89 | 91 | lock (this) { | 
|  | 90 | if (m_state == State.Cancelled) | |
|  | 92 | if (m_state == PromiseState.Cancelled) | |
|  | 91 | 93 | return; | 
|  | 92 | if (m_state != State.Unresolved) | |
|  | 94 | if (m_state != PromiseState.Unresolved) | |
|  | 93 | 95 | throw new InvalidOperationException("The promise is already resolved"); | 
|  | 94 | 96 | m_result = result; | 
|  | 95 | m_state = State.Resolv | |
|  | 97 | m_state = PromiseState.Resolved; | |
|  | 96 | 98 | } | 
|  | 97 | 99 | |
|  | 98 | 100 | ResultHandlerInfo handler; | 
| @@ -107,12 +109,12 namespace Implab { | |||
|  | 107 | 109 | /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> | 
|  | 108 | 110 | public void Reject(Exception error) { | 
|  | 109 | 111 | lock (this) { | 
|  | 110 | if (m_state == State.Cancelled) | |
|  | 112 | if (m_state == PromiseState.Cancelled) | |
|  | 111 | 113 | return; | 
|  | 112 | if (m_state != State.Unresolved) | |
|  | 114 | if (m_state != PromiseState.Unresolved) | |
|  | 113 | 115 | throw new InvalidOperationException("The promise is already resolved"); | 
|  | 114 | 116 | m_error = error; | 
|  | 115 | m_state = State.Re | |
|  | 117 | m_state = PromiseState.Rejected; | |
|  | 116 | 118 | } | 
|  | 117 | 119 | |
|  | 118 | 120 | ResultHandlerInfo handler; | 
| @@ -126,8 +128,9 namespace Implab { | |||
|  | 126 | 128 | /// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns> | 
|  | 127 | 129 | public bool Cancel() { | 
|  | 128 | 130 | lock (this) { | 
|  | 129 | if (m_state == State.Unresolved && m_cancellable) | |
|  | 130 | m_state = State.Cancelled; | |
|  | 131 | if (m_state == PromiseState.Unresolved && m_cancellable) | |
|  | 132 | { | |
|  | 133 | m_state = PromiseState.Cancelled; | |
|  | 131 | 134 | EventHandler temp = Cancelled; | 
|  | 132 | 135 | |
|  | 133 | 136 | if (temp != null) | 
| @@ -348,14 +351,13 namespace Implab { | |||
|  | 348 | 351 | handler = default(ResultHandlerInfo); | 
|  | 349 | 352 | |
|  | 350 | 353 | lock (this) { | 
|  | 351 | Debug.Assert(m_state | |
|  | 354 | Debug.Assert(m_state != PromiseState.Unresolved); | |
|  | 352 | 355 | |
|  | 353 | 356 | if (m_handlersChain.Count > 0) { | 
|  | 354 | 357 | handler = m_handlersChain.First.Value; | 
|  | 355 | 358 | m_handlersChain.RemoveFirst(); | 
|  | 356 | 359 | return true; | 
|  | 357 | 360 | } else { | 
|  | 358 | m_state = State.Resolved; | |
|  | 359 | 361 | return false; | 
|  | 360 | 362 | } | 
|  | 361 | 363 | } | 
| @@ -365,7 +367,7 namespace Implab { | |||
|  | 365 | 367 | bool invokeRequired = false; | 
|  | 366 | 368 | |
|  | 367 | 369 | lock (this) { | 
|  | 368 | if (m_state | |
|  | 370 | if (m_state == PromiseState.Unresolved) | |
|  | 369 | 371 | m_handlersChain.AddLast(handler); | 
|  | 370 | 372 | else | 
|  | 371 | 373 | invokeRequired = true; | 
        
        General Comments 0
    
    
  
  
                      You need to be logged in to leave comments.
                      Login now
                    
                