Mercurial > pub > ImplabNet
comparison Implab/Promise.cs @ 7:7ea9363fef6c promises
inital progress handling
author | cin |
---|---|
date | Fri, 01 Nov 2013 16:03:08 +0400 |
parents | dfa21d507bc5 |
children | c82e0dfbb4dd |
comparison
equal
deleted
inserted
replaced
6:dfa21d507bc5 | 7:7ea9363fef6c |
---|---|
46 /// <para> | 46 /// <para> |
47 /// Также хорошим правилом является то, что <c>Resolve</c> и <c>Reject</c> должен вызывать | 47 /// Также хорошим правилом является то, что <c>Resolve</c> и <c>Reject</c> должен вызывать |
48 /// только инициатор обещания иначе могут возникнуть противоречия. | 48 /// только инициатор обещания иначе могут возникнуть противоречия. |
49 /// </para> | 49 /// </para> |
50 /// </remarks> | 50 /// </remarks> |
51 public class Promise<T> { | 51 public class Promise<T>: IPromise { |
52 | 52 |
53 struct ResultHandlerInfo { | 53 struct ResultHandlerInfo { |
54 public ResultHandler<T> resultHandler; | 54 public ResultHandler<T> resultHandler; |
55 public ErrorHandler errorHandler; | 55 public ErrorHandler errorHandler; |
56 } | 56 public Action cancelHandler; |
57 | |
58 enum State { | |
59 Unresolved, | |
60 Resolving, | |
61 Resolved, | |
62 Cancelled | |
63 } | 57 } |
64 | 58 |
65 LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>(); | 59 LinkedList<ResultHandlerInfo> m_handlersChain = new LinkedList<ResultHandlerInfo>(); |
66 State m_state; | 60 PromiseState m_state; |
67 bool m_cancellable; | 61 bool m_cancellable; |
68 T m_result; | 62 T m_result; |
69 Exception m_error; | 63 Exception m_error; |
64 IPromise m_parent; | |
65 int m_childrenCount; | |
70 | 66 |
71 public Promise() { | 67 public Promise() { |
72 m_cancellable = true; | 68 m_cancellable = true; |
69 } | |
70 | |
71 public Promise(IPromise parent, bool cancellable) | |
72 { | |
73 m_cancellable = cancellable; | |
74 m_parent = parent; | |
73 } | 75 } |
74 | 76 |
75 /// <summary> | 77 /// <summary> |
76 /// Событие, возникающее при отмене асинхронной операции. | 78 /// Событие, возникающее при отмене асинхронной операции. |
77 /// </summary> | 79 /// </summary> |
85 /// </summary> | 87 /// </summary> |
86 /// <param name="result">Результат выполнения.</param> | 88 /// <param name="result">Результат выполнения.</param> |
87 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> | 89 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> |
88 public void Resolve(T result) { | 90 public void Resolve(T result) { |
89 lock (this) { | 91 lock (this) { |
90 if (m_state == State.Cancelled) | 92 if (m_state == PromiseState.Cancelled) |
91 return; | 93 return; |
92 if (m_state != State.Unresolved) | 94 if (m_state != PromiseState.Unresolved) |
93 throw new InvalidOperationException("The promise is already resolved"); | 95 throw new InvalidOperationException("The promise is already resolved"); |
94 m_result = result; | 96 m_result = result; |
95 m_state = State.Resolving; | 97 m_state = PromiseState.Resolved; |
96 } | 98 } |
97 | 99 |
98 ResultHandlerInfo handler; | 100 ResultHandlerInfo handler; |
99 while (FetchNextHandler(out handler)) | 101 while (FetchNextHandler(out handler)) |
100 InvokeHandler(handler); | 102 InvokeHandler(handler); |
105 /// </summary> | 107 /// </summary> |
106 /// <param name="error">Исключение возникшее при выполнении операции</param> | 108 /// <param name="error">Исключение возникшее при выполнении операции</param> |
107 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> | 109 /// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception> |
108 public void Reject(Exception error) { | 110 public void Reject(Exception error) { |
109 lock (this) { | 111 lock (this) { |
110 if (m_state == State.Cancelled) | 112 if (m_state == PromiseState.Cancelled) |
111 return; | 113 return; |
112 if (m_state != State.Unresolved) | 114 if (m_state != PromiseState.Unresolved) |
113 throw new InvalidOperationException("The promise is already resolved"); | 115 throw new InvalidOperationException("The promise is already resolved"); |
114 m_error = error; | 116 m_error = error; |
115 m_state = State.Resolving; | 117 m_state = PromiseState.Rejected; |
116 } | 118 } |
117 | 119 |
118 ResultHandlerInfo handler; | 120 ResultHandlerInfo handler; |
119 while (FetchNextHandler(out handler)) | 121 while (FetchNextHandler(out handler)) |
120 InvokeHandler(handler); | 122 InvokeHandler(handler); |
124 /// Отменяет операцию, если это возможно. | 126 /// Отменяет операцию, если это возможно. |
125 /// </summary> | 127 /// </summary> |
126 /// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns> | 128 /// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns> |
127 public bool Cancel() { | 129 public bool Cancel() { |
128 lock (this) { | 130 lock (this) { |
129 if (m_state == State.Unresolved && m_cancellable) { | 131 if (m_state == PromiseState.Unresolved && m_cancellable) |
130 m_state = State.Cancelled; | 132 { |
133 m_state = PromiseState.Cancelled; | |
131 EventHandler temp = Cancelled; | 134 EventHandler temp = Cancelled; |
132 | 135 |
133 if (temp != null) | 136 if (temp != null) |
134 temp(this, new EventArgs()); | 137 temp(this, new EventArgs()); |
135 | 138 |
346 /// <returns>Признак того, что еще остались обработчики в очереди</returns> | 349 /// <returns>Признак того, что еще остались обработчики в очереди</returns> |
347 bool FetchNextHandler(out ResultHandlerInfo handler) { | 350 bool FetchNextHandler(out ResultHandlerInfo handler) { |
348 handler = default(ResultHandlerInfo); | 351 handler = default(ResultHandlerInfo); |
349 | 352 |
350 lock (this) { | 353 lock (this) { |
351 Debug.Assert(m_state == State.Resolving); | 354 Debug.Assert(m_state != PromiseState.Unresolved); |
352 | 355 |
353 if (m_handlersChain.Count > 0) { | 356 if (m_handlersChain.Count > 0) { |
354 handler = m_handlersChain.First.Value; | 357 handler = m_handlersChain.First.Value; |
355 m_handlersChain.RemoveFirst(); | 358 m_handlersChain.RemoveFirst(); |
356 return true; | 359 return true; |
357 } else { | 360 } else { |
358 m_state = State.Resolved; | |
359 return false; | 361 return false; |
360 } | 362 } |
361 } | 363 } |
362 } | 364 } |
363 | 365 |
364 void AddHandler(ResultHandlerInfo handler) { | 366 void AddHandler(ResultHandlerInfo handler) { |
365 bool invokeRequired = false; | 367 bool invokeRequired = false; |
366 | 368 |
367 lock (this) { | 369 lock (this) { |
368 if (m_state != State.Resolved) | 370 if (m_state == PromiseState.Unresolved) |
369 m_handlersChain.AddLast(handler); | 371 m_handlersChain.AddLast(handler); |
370 else | 372 else |
371 invokeRequired = true; | 373 invokeRequired = true; |
372 } | 374 } |
373 | 375 |