##// END OF EJS Templates
working on promises
working on promises

File last commit:

r243:b1e0ffdf3451 v3
r243:b1e0ffdf3451 v3
Show More
AbstractPromise.cs
146 lines | 4.6 KiB | text/x-csharp | CSharpLexer
/ Implab / AbstractPromise.cs
cin
Promises rewritten, added improved version of AsyncQueue
r119 using System;
cin
working on promises
r243 using System.Diagnostics;
using System.Reflection;
cin
Promises rewritten, added improved version of AsyncQueue
r119 using Implab.Parallels;
namespace Implab {
cin
DRAFT: refactoring
r144 public abstract class AbstractPromise : AbstractEvent<AbstractPromise.HandlerDescriptor>, IPromise {
cin
Working on promises
r242 public class HandlerDescriptor {
cin
working on promises
r243 readonly Action m_resolve;
readonly Action<Exception> m_reject;
readonly IDeferred m_deferred;
cin
Working on promises
r242 public HandlerDescriptor(Action success, Action<Exception> error) {
cin
working on promises
r243 m_resolve = success;
m_reject = error;
cin
DRAFT: refactoring
r144 }
cin
Promises rewritten, added improved version of AsyncQueue
r119
cin
DRAFT: refactoring
r144 public void SignalSuccess() {
cin
working on promises
r243 try {
if (m_resolve != null)
m_resolve();
m_deferred.Resolve();
} catch (Exception ex) {
m_deferred.Reject(ex);
cin
DRAFT: refactoring
r144 }
}
cin
Promises rewritten, added improved version of AsyncQueue
r119
cin
DRAFT: refactoring
r144 public void SignalError(Exception err) {
cin
working on promises
r243 if (m_reject != null) {
cin
DRAFT: refactoring
r144 try {
cin
working on promises
r243 m_reject(err);
m_deferred.Resolve();
} catch (Exception ex) {
m_deferred.Reject(ex);
cin
DRAFT: refactoring
r144 }
}
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
}
cin
working on promises
r243 PromiseState m_state;
Exception m_error;
public bool IsRejected {
get {
return m_state == PromiseState.Rejected;
}
}
public bool IsResolved {
get {
return m_state == PromiseState.Resolved;
}
}
public Exception RejectReason {
get {
return m_error;
}
}
cin
Promises rewritten, added improved version of AsyncQueue
r119
cin
DRAFT: refactoring
r144 #region implemented abstract members of AbstractPromise
cin
Promises rewritten, added improved version of AsyncQueue
r119
cin
working on promises
r243 protected override void SignalHandler(HandlerDescriptor handler) {
switch (m_state) {
case PromiseState.Resolved:
cin
Promises: SignalXXX methods merged into SignalHandler method....
r156 handler.SignalSuccess();
break;
cin
working on promises
r243 case PromiseState.Rejected:
cin
Working on promises
r242 handler.SignalError(RejectReason);
cin
Promises: SignalXXX methods merged into SignalHandler method....
r156 break;
default:
cin
working on promises
r243 throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", m_state));
cin
Promises: SignalXXX methods merged into SignalHandler method....
r156 }
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
cin
Working on promises
r242 protected override Signal GetFulfillSignal() {
cin
DRAFT: refactoring
r144 var signal = new Signal();
cin
Working on promises
r242 On(signal.Set, e => signal.Set());
cin
RC: cancellation support for promises + tests
r145 return signal;
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
#endregion
cin
working on promises
r243 protected void CompleteResolve() {
m_state = PromiseState.Resolved;
CompleteTransit();
}
cin
Working on promises
r242 public Type ResultType {
cin
DRAFT: refactoring
r144 get {
return typeof(void);
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
}
cin
working on promises
r243 /// <summary>
/// Выполняет обещание, сообщая об ошибке
/// </summary>
/// <remarks>
/// Поскольку обещание должно работать в многопточной среде, при его выполнении сразу несколько потоков
/// могу вернуть ошибку, при этом только первая будет использована в качестве результата, остальные
/// будут проигнорированы.
/// </remarks>
/// <param name="error">Исключение возникшее при выполнении операции</param>
/// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
protected void SetError(Exception error) {
if (BeginTransit()) {
m_error = error;
m_state = PromiseState.Rejected;
CompleteTransit();
} else {
WaitTransition();
if (m_state == PromiseState.Resolved)
throw new InvalidOperationException("The promise is already resolved");
}
}
protected void Rethrow() {
Debug.Assert(m_error != null);
if (m_error is OperationCanceledException)
throw new OperationCanceledException("Operation cancelled", m_error);
else
throw new TargetInvocationException(m_error);
}
cin
Working on promises
r242 public void On(Action success, Action<Exception> error) {
AddHandler(new HandlerDescriptor(success, error));
cin
DRAFT: refactoring
r144 }
cin
Promises rewritten, added improved version of AsyncQueue
r119
cin
DRAFT: refactoring
r144 public IPromise<T> Cast<T>() {
throw new InvalidCastException();
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
public void Join() {
WaitResult(-1);
cin
working on promises
r243 if (IsRejected)
Rethrow();
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
cin
DRAFT: refactoring
r144 public void Join(int timeout) {
WaitResult(timeout);
cin
Promises rewritten, added improved version of AsyncQueue
r119 }
}
}