##// END OF EJS Templates
Added Skip method to JSON parser to skip contents of the current node
Added Skip method to JSON parser to skip contents of the current node

File last commit:

r33:b255e4aeef17 default
r62:62b440d46313 default
Show More
Promise.cs
762 lines | 32.1 KiB | text/x-csharp | CSharpLexer
cin
small fixes
r2 using System;
using System.Collections.Generic;
using System.Reflection;
using System.Diagnostics;
using System.Threading;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 using Implab.Parallels;
cin
small fixes
r2
namespace Implab {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 public delegate void ErrorHandler(Exception e);
cin
refactoring
r11 public delegate T ErrorHandler<out T>(Exception e);
cin
implemeted new cancellable promises concept
r10 public delegate void ResultHandler<in T>(T result);
public delegate TNew ResultMapper<in TSrc, out TNew>(TSrc result);
cin
removed the reference to the parent from the promise object this allows...
r33 public delegate IPromise<TNew> ChainedOperation<in TSrc, TNew>(TSrc result);
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
/// Класс для асинхронного получения результатов. Так называемое "обещание".
/// </summary>
/// <typeparam name="T">Тип получаемого результата</typeparam>
/// <remarks>
/// <para>Сервис при обращении к его методу дает обещаиние о выполнении операции,
/// клиент получив такое обещание может установить ряд обратных вызово для получения
/// событий выполнения обещания, тоесть завершения операции и предоставлении результатов.</para>
/// <para>
/// Обещение может быть как выполнено, так и выполнено с ошибкой. Для подписки на
/// данные события клиент должен использовать методы <c>Then</c>.
/// </para>
/// <para>
/// Сервис, в свою очередь, по окончанию выполнения операции (возможно с ошибкой),
/// использует методы <c>Resolve</c> либо <c>Reject</c> для оповещения клиетна о
/// выполнении обещания.
/// </para>
/// <para>
/// Если сервер успел выполнить обещание еще до того, как клиент на него подписался,
/// то в момент подписки клиента будут вызваны соответсвующие события в синхронном
/// режиме и клиент будет оповещен в любом случае. Иначе, обработчики добавляются в
/// список в порядке подписания и в этом же порядке они будут вызваны при выполнении
/// обещания.
/// </para>
/// <para>
/// Обрабатывая результаты обещания можно преобразовывать результаты либо инициировать
/// связанные асинхронные операции, которые также возвращают обещания. Для этого следует
/// использовать соответствующую форму методе <c>Then</c>.
/// </para>
/// <para>
/// Также хорошим правилом является то, что <c>Resolve</c> и <c>Reject</c> должен вызывать
/// только инициатор обещания иначе могут возникнуть противоречия.
/// </para>
/// </remarks>
cin
refactoring
r25 public class Promise<T> : IPromise<T> {
cin
small fixes
r2
cin
fixes
r28 protected struct HandlerDescriptor {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 public ResultHandler<T> resultHandler;
public ErrorHandler errorHandler;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 public Action cancellHandler;
public void Resolve(T result) {
if (resultHandler != null)
try {
resultHandler(result);
} catch (Exception e) {
Reject(e);
}
}
public void Reject(Exception err) {
if (errorHandler != null)
try {
errorHandler(err);
} catch {
}
}
public void Cancel() {
if (cancellHandler != null)
try {
cancellHandler();
} catch {
}
}
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
Promise is rewritten to use interlocked operations instead of locks
r19 const int UnresolvedSate = 0;
const int TransitionalState = 1;
cin
refactoring
r25 const int SucceededState = 2;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 const int RejectedState = 3;
const int CancelledState = 4;
readonly bool m_cancellable;
cin
sync
r9
cin
implemeted new cancellable promises concept
r10 int m_childrenCount = 0;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 int m_state;
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 T m_result;
Exception m_error;
cin
sync
r9
cin
Promise is rewritten to use interlocked operations instead of locks
r19 readonly MTQueue<HandlerDescriptor> m_handlers = new MTQueue<HandlerDescriptor>();
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 public Promise() {
m_cancellable = true;
}
cin
small fixes
r2
cin
refactoring
r25 public Promise(IPromiseBase parent, bool cancellable) {
cin
inital progress handling
r7 m_cancellable = cancellable;
cin
removed the reference to the parent from the promise object this allows...
r33 if (parent != null)
AddHandler(
null,
null,
() => {
if (parent.IsExclusive)
parent.Cancel();
}
);
cin
implemeted new cancellable promises concept
r10 }
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 bool BeginTransit() {
return UnresolvedSate == Interlocked.CompareExchange(ref m_state, TransitionalState, UnresolvedSate);
}
void CompleteTransit(int state) {
if (TransitionalState != Interlocked.CompareExchange(ref m_state, state, TransitionalState))
throw new InvalidOperationException("Can't complete transition when the object isn't in the transitional state");
}
cin
refactoring
r25 void WaitTransition() {
while (m_state == TransitionalState) {
/* noop */
}
}
cin
Promise is rewritten to use interlocked operations instead of locks
r19 public bool IsResolved {
get {
return m_state > 1;
}
}
public bool IsCancelled {
get {
return m_state == CancelledState;
}
}
cin
Added a casting method for promises.
r29 public Type PromiseType {
get { return typeof(T); }
}
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
/// Выполняет обещание, сообщая об успешном выполнении.
/// </summary>
/// <param name="result">Результат выполнения.</param>
/// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
public void Resolve(T result) {
cin
Promise is rewritten to use interlocked operations instead of locks
r19 if (BeginTransit()) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 m_result = result;
cin
refactoring
r25 CompleteTransit(SucceededState);
cin
Promise is rewritten to use interlocked operations instead of locks
r19 OnStateChanged();
cin
refactoring
r25 } else {
WaitTransition();
if (m_state != CancelledState)
throw new InvalidOperationException("The promise is already resolved");
}
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
cin
removed the reference to the parent from the promise object this allows...
r33 /// Выполняет обещание, сообщая об успешном выполнении. Результатом выполнения будет пустое значения.
/// </summary>
/// <remarks>
/// Данный вариант удобен в случаях, когда интересен факт выполнения операции, нежели полученное значение.
/// </remarks>
public void Resolve() {
Resolve(default(T));
}
/// <summary>
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// Выполняет обещание, сообщая об ошибке
/// </summary>
cin
sync
r16 /// <remarks>
/// Поскольку обещание должно работать в многопточной среде, при его выполнении сразу несколько потоков
/// могу вернуть ошибку, при этом только первая будет использована в качестве результата, остальные
/// будут проигнорированы.
/// </remarks>
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <param name="error">Исключение возникшее при выполнении операции</param>
/// <exception cref="InvalidOperationException">Данное обещание уже выполнено</exception>
public void Reject(Exception error) {
cin
Promise is rewritten to use interlocked operations instead of locks
r19 if (BeginTransit()) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 m_error = error;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 CompleteTransit(RejectedState);
OnStateChanged();
cin
refactoring
r25 } else {
WaitTransition();
if (m_state == SucceededState)
throw new InvalidOperationException("The promise is already resolved");
}
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
/// Отменяет операцию, если это возможно.
/// </summary>
/// <returns><c>true</c> Операция была отменена, обработчики не будут вызваны.<c>false</c> отмена не возможна, поскольку обещание уже выполнено и обработчики отработали.</returns>
public bool Cancel() {
cin
removed the reference to the parent from the promise object this allows...
r33 if (BeginTransit()) {
CompleteTransit(CancelledState);
OnStateChanged();
return true;
} else {
return false;
}
}
// сделано для возвращаемого типа void
protected void InternalCancel() {
Cancel();
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
cin
refactoring
r11 /// Adds new handlers to this promise.
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// </summary>
cin
refactoring
r11 /// <param name="success">The handler of the successfully completed operation.
/// This handler will recieve an operation result as a parameter.</param>
/// <param name="error">Handles an exception that may occur during the operation.</param>
/// <returns>The new promise chained to this one.</returns>
cin
refactoring
r26 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler error) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 if (success == null && error == null)
return this;
cin
refactoring
r11 var medium = new Promise<T>(this, true);
cin
*refactoring: Promise.Then now returns a new chained promise...
r6
cin
Promise is rewritten to use interlocked operations instead of locks
r19 ResultHandler<T> resultHandler;
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 if (success != null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 resultHandler = x => {
cin
implemeted new cancellable promises concept
r10 success(x);
medium.Resolve(x);
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 };
else
cin
Promise is rewritten to use interlocked operations instead of locks
r19 resultHandler = medium.Resolve;
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 ErrorHandler errorHandler;
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 if (error != null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 errorHandler = x => {
cin
refactoring
r25 // несмотря на то, что обработчик ошибки вызывается безопасно,
// т.е. возникшие в нем ошибки будут подавлены, нам нужно
// гарантировать, что ошибка будет передана дальше по цепочке обещаний
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 try {
error(x);
} catch { }
medium.Reject(x);
};
else
cin
Promise is rewritten to use interlocked operations instead of locks
r19 errorHandler = medium.Reject;
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 AddHandler(resultHandler, errorHandler, medium.InternalCancel);
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 return medium;
}
cin
small fixes
r2
cin
removed the reference to the parent from the promise object this allows...
r33 public IPromiseBase Then(Action success, ErrorHandler error) {
cin
refactoring
r26 return Then(x => success(), error);
}
cin
removed the reference to the parent from the promise object this allows...
r33 public IPromiseBase Then(Action success) {
cin
fixed: StackOverflow in IPromiseBase.Then(handler)...
r32 return Then(x => success());
cin
refactoring
r26 }
cin
refactoring
r11 /// <summary>
/// Adds new handlers to this promise.
/// </summary>
/// <param name="success">The handler of the successfully completed operation.
/// This handler will recieve an operation result as a parameter.</param>
/// <param name="error">Handles an exception that may occur during the operation and returns the value which will be used as the result of the operation.</param>
/// <returns>The new promise chained to this one.</returns>
cin
refactoring
r26 public IPromise<T> Then(ResultHandler<T> success, ErrorHandler<T> error) {
cin
refactoring
r11 if (success == null && error == null)
return this;
var medium = new Promise<T>(this, true);
cin
Promise is rewritten to use interlocked operations instead of locks
r19 ResultHandler<T> resultHandler;
ErrorHandler errorHandler;
cin
refactoring
r11
if (success != null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 resultHandler = x => {
cin
refactoring
r11 success(x);
medium.Resolve(x);
};
else
cin
Promise is rewritten to use interlocked operations instead of locks
r19 resultHandler = medium.Resolve;
cin
refactoring
r11
if (error != null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 errorHandler = x => {
cin
refactoring
r11 try {
medium.Resolve(error(x));
cin
removed the reference to the parent from the promise object this allows...
r33 } catch (Exception e) {
cin
refactoring
r25 medium.Reject(e);
}
cin
refactoring
r11 };
else
cin
Promise is rewritten to use interlocked operations instead of locks
r19 errorHandler = medium.Reject;
cin
refactoring
r11
cin
Promise is rewritten to use interlocked operations instead of locks
r19 AddHandler(resultHandler, errorHandler, medium.InternalCancel);
cin
refactoring
r11
return medium;
}
cin
refactoring
r26 public IPromise<T> Then(ResultHandler<T> success) {
cin
refactoring
r11 if (success == null)
return this;
var medium = new Promise<T>(this, true);
cin
Promise is rewritten to use interlocked operations instead of locks
r19 ResultHandler<T> resultHandler;
cin
refactoring
r25
cin
refactoring
r11 if (success != null)
cin
Promise is rewritten to use interlocked operations instead of locks
r19 resultHandler = x => {
cin
refactoring
r11 success(x);
medium.Resolve(x);
};
else
cin
Promise is rewritten to use interlocked operations instead of locks
r19 resultHandler = medium.Resolve;
cin
refactoring
r11
cin
Promise is rewritten to use interlocked operations instead of locks
r19 AddHandler(resultHandler, medium.Reject, medium.InternalCancel);
cin
refactoring
r11
return medium;
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2
cin
refactoring
r26 public IPromise<T> Error(ErrorHandler error) {
return Then((ResultHandler<T>)null, error);
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2
cin
refactoring
r11 /// <summary>
/// Handles error and allows to keep the promise.
/// </summary>
/// <remarks>
/// If the specified handler throws an exception, this exception will be used to reject the promise.
/// </remarks>
/// <param name="handler">The error handler which returns the result of the promise.</param>
/// <returns>New promise.</returns>
cin
refactoring
r26 public IPromise<T> Error(ErrorHandler<T> handler) {
cin
refactoring
r11 if (handler == null)
return this;
var medium = new Promise<T>(this, true);
cin
Promise is rewritten to use interlocked operations instead of locks
r19 AddHandler(
cin
fixes
r27 x => medium.Resolve(x),
cin
Promise is rewritten to use interlocked operations instead of locks
r19 e => {
cin
refactoring
r11 try {
medium.Resolve(handler(e));
} catch (Exception e2) {
medium.Reject(e2);
}
cin
Promise is rewritten to use interlocked operations instead of locks
r19 },
medium.InternalCancel
);
cin
refactoring
r11
return medium;
}
cin
refactoring
r26 public IPromise<T> Anyway(Action handler) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 if (handler == null)
return this;
cin
removed the reference to the parent from the promise object this allows...
r33 var medium = new Promise<T>(this,true);
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 AddHandler(
x => {
cin
implemeted new cancellable promises concept
r10 // to avoid handler being called multiple times we handle exception by ourselfs
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 try {
handler();
medium.Resolve(x);
} catch (Exception e) {
medium.Reject(e);
}
},
cin
Promise is rewritten to use interlocked operations instead of locks
r19
e => {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 try {
handler();
} catch { }
cin
Promise is rewritten to use interlocked operations instead of locks
r19 medium.Reject(e);
},
medium.InternalCancel
);
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 return medium;
}
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
/// Позволяет преобразовать результат выполения операции к новому типу.
/// </summary>
/// <typeparam name="TNew">Новый тип результата.</typeparam>
/// <param name="mapper">Преобразование результата к новому типу.</param>
/// <param name="error">Обработчик ошибки. Данный обработчик получит
/// исключение возникшее при выполнении операции.</param>
/// <returns>Новое обещание, которое будет выполнено при выполнении исходного обещания.</returns>
cin
refactoring
r26 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper, ErrorHandler error) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 if (mapper == null)
throw new ArgumentNullException("mapper");
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 // создаем прицепленное обещание
cin
removed the reference to the parent from the promise object this allows...
r33 var chained = new Promise<TNew>(this,true);
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 ResultHandler<T> resultHandler = result => chained.Resolve(mapper(result));
ErrorHandler errorHandler = delegate(Exception e) {
if (error != null)
try {
error(e);
} catch { }
// в случае ошибки нужно передать исключение дальше по цепочке
chained.Reject(e);
};
AddHandler(
resultHandler,
errorHandler,
chained.InternalCancel
);
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 return chained;
}
cin
refactoring
r26 public IPromise<TNew> Map<TNew>(ResultMapper<T, TNew> mapper) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 return Map(mapper, null);
}
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
/// Сцепляет несколько аснхронных операций. Указанная асинхронная операция будет вызвана после
/// выполнения текущей, а результат текущей операции может быть использован для инициализации
/// новой операции.
/// </summary>
/// <typeparam name="TNew">Тип результата указанной асинхронной операции.</typeparam>
/// <param name="chained">Асинхронная операция, которая должна будет начаться после выполнения текущей.</param>
/// <param name="error">Обработчик ошибки. Данный обработчик получит
/// исключение возникшее при выполнении текуещй операции.</param>
/// <returns>Новое обещание, которое будет выполнено по окончанию указанной аснхронной операции.</returns>
cin
refactoring
r26 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained, ErrorHandler error) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6
// проблема в том, что на момент связывания еще не начата асинхронная операция, поэтому нужно
// создать посредника, к которому будут подвызяваться следующие обработчики.
// когда будет выполнена реальная асинхронная операция, она обратиться к посреднику, чтобы
// передать через него результаты работы.
cin
implemeted new cancellable promises concept
r10 var medium = new Promise<TNew>(this, true);
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 ResultHandler<T> resultHandler = delegate(T result) {
if (medium.IsCancelled)
return;
cin
implemeted new cancellable promises concept
r10
cin
Promise is rewritten to use interlocked operations instead of locks
r19 var promise = chained(result);
cin
implemeted new cancellable promises concept
r10
cin
Promise is rewritten to use interlocked operations instead of locks
r19 promise.Then(
x => medium.Resolve(x),
e => medium.Reject(e)
);
cin
removed the reference to the parent from the promise object this allows...
r33
// notify chained operation that it's not needed anymore
// порядок вызова Then, Cancelled важен, поскольку от этого
// зависит IsExclusive
medium.Cancelled(() => {
if(promise.IsExclusive)
promise.Cancel();
});
// внешняя отмена связанной операции рассматривается как ошибка
promise.Cancelled(() => medium.Reject(new OperationCanceledException()));
cin
Promise is rewritten to use interlocked operations instead of locks
r19 };
ErrorHandler errorHandler = delegate(Exception e) {
if (error != null)
error(e);
// в случае ошибки нужно передать исключение дальше по цепочке
medium.Reject(e);
};
AddHandler(
resultHandler,
errorHandler,
medium.InternalCancel
);
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 return medium;
}
cin
refactoring
r26 public IPromise<TNew> Chain<TNew>(ChainedOperation<T, TNew> chained) {
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 return Chain(chained, null);
}
cin
small fixes
r2
cin
refactoring
r26 public IPromise<T> Cancelled(Action handler) {
cin
Promise is rewritten to use interlocked operations instead of locks
r19 AddHandler(null, null, handler);
cin
implemeted new cancellable promises concept
r10 return this;
}
cin
refactoring
r25 /// <summary>
/// Adds the specified handler for all cases (success, error, cancel)
/// </summary>
/// <param name="handler">The handler that will be called anyway</param>
/// <returns>self</returns>
cin
refactoring
r26 public IPromise<T> Finally(Action handler) {
cin
Promise is rewritten to use interlocked operations instead of locks
r19 if (handler == null)
throw new ArgumentNullException("handler");
AddHandler(
x => handler(),
e => handler(),
handler
);
return this;
cin
implemeted new cancellable promises concept
r10 }
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// <summary>
cin
Added a casting method for promises.
r29 /// Преобразует результат обещания к нужному типу
/// </summary>
/// <typeparam name="T2"></typeparam>
/// <returns></returns>
public IPromise<T2> Cast<T2>() {
return Map(x => (T2)(object)x, null);
}
/// <summary>
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 /// Дожидается отложенного обещания и в случае успеха, возвращает
/// его, результат, в противном случае бросает исключение.
/// </summary>
/// <remarks>
/// <para>
/// Если ожидание обещания было прервано по таймауту, это не значит,
/// что обещание было отменено или что-то в этом роде, это только
/// означает, что мы его не дождались, однако все зарегистрированные
/// обработчики, как были так остались и они будут вызваны, когда
/// обещание будет выполнено.
/// </para>
/// <para>
/// Такое поведение вполне оправдано поскольку таймаут может истечь
/// в тот момент, когда началась обработка цепочки обработчиков, и
/// к тому же текущее обещание может стоять в цепочке обещаний и его
/// отклонение может привести к непрогнозируемому результату.
/// </para>
/// </remarks>
/// <param name="timeout">Время ожидания</param>
/// <returns>Результат выполнения обещания</returns>
public T Join(int timeout) {
cin
implemeted new cancellable promises concept
r10 var evt = new ManualResetEvent(false);
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 Anyway(() => evt.Set());
cin
implemeted new cancellable promises concept
r10 Cancelled(() => evt.Set());
cin
small fixes
r2
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 if (!evt.WaitOne(timeout, true))
throw new TimeoutException();
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 switch (m_state) {
cin
refactoring
r25 case SucceededState:
cin
implemeted new cancellable promises concept
r10 return m_result;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 case CancelledState:
cin
implemeted new cancellable promises concept
r10 throw new OperationCanceledException();
cin
Promise is rewritten to use interlocked operations instead of locks
r19 case RejectedState:
cin
implemeted new cancellable promises concept
r10 throw new TargetInvocationException(m_error);
default:
cin
Promise is rewritten to use interlocked operations instead of locks
r19 throw new ApplicationException(String.Format("Invalid promise state {0}", m_state));
cin
implemeted new cancellable promises concept
r10 }
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
public T Join() {
return Join(Timeout.Infinite);
}
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 void AddHandler(ResultHandler<T> success, ErrorHandler error, Action cancel) {
cin
removed the reference to the parent from the promise object this allows...
r33 if (success != null || error != null)
Interlocked.Increment(ref m_childrenCount);
cin
Promise is rewritten to use interlocked operations instead of locks
r19
HandlerDescriptor handler = new HandlerDescriptor {
resultHandler = success,
errorHandler = error,
cancellHandler = cancel
};
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 bool queued;
if (!IsResolved) {
m_handlers.Enqueue(handler);
queued = true;
} else {
// the promise is in resolved state, just invoke the handled with minimum overhead
queued = false;
InvokeHandler(handler);
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2
cin
Promise is rewritten to use interlocked operations instead of locks
r19 if (queued && IsResolved && m_handlers.TryDequeue(out handler))
// if the promise have been resolved while we was adding handler to the queue
// we can't guarantee that someone is still processing it
// therefore we will fetch a handler from the queue and execute it
cin
fixes
r27 // note that fetched handler may be not the one that we have added
// even we can fetch no handlers at all :)
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 InvokeHandler(handler);
}
cin
small fixes
r2
cin
fixes
r27 protected virtual void InvokeHandler(HandlerDescriptor handler) {
cin
implemeted new cancellable promises concept
r10 switch (m_state) {
cin
refactoring
r25 case SucceededState:
cin
Promise is rewritten to use interlocked operations instead of locks
r19 handler.Resolve(m_result);
cin
implemeted new cancellable promises concept
r10 break;
cin
Promise is rewritten to use interlocked operations instead of locks
r19 case RejectedState:
handler.Reject(m_error);
break;
case CancelledState:
handler.Cancel();
cin
implemeted new cancellable promises concept
r10 break;
default:
// do nothing
return;
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
}
cin
small fixes
r2
cin
refactoring
r11 protected virtual void OnStateChanged() {
cin
Promise is rewritten to use interlocked operations instead of locks
r19 HandlerDescriptor handler;
while (m_handlers.TryDequeue(out handler))
InvokeHandler(handler);
cin
refactoring
r11 }
cin
sync
r9 public bool IsExclusive {
get {
cin
Promise is rewritten to use interlocked operations instead of locks
r19 return m_childrenCount <= 1;
cin
sync
r9 }
}
cin
refactoring
r25 /// <summary>
/// Объединяет несколько обещаний в одно, результатом которого является массив результатов других обещаний.
/// Если хотябы одно из переданных обещаний не будет выполнено, то новое обещение тоже не будет выполнено.
/// При отмене нового обещания, переданные обещания также будут отменены, если никто больше на них не подписан.
/// </summary>
/// <param name="promises">Список обещаний. Если список пустой, то результирующее обещание возвращается уже выполненным.</param>
/// <returns>Обещание объединяющее в себе результат переданных обещаний.</returns>
/// <exception cref="ArgumentNullException"><paramref name="promises"/> не может быть null</exception>
cin
small refactoring, cleanup.
r30 public static IPromise<T[]> CreateComposite(IList<IPromise<T>> promises) {
cin
refactoring
r25 if (promises == null)
throw new ArgumentNullException();
// создаем аккумулятор для результатов и результирующее обещание
var result = new T[promises.Count];
var promise = new Promise<T[]>();
// special case
if (promises.Count == 0) {
promise.Resolve(result);
return promise;
}
int pending = promises.Count;
for (int i = 0; i < promises.Count; i++) {
var dest = i;
cin
removed the reference to the parent from the promise object this allows...
r33 if (promises[i] != null) {
promises[i].Then(
x => {
result[dest] = x;
if (Interlocked.Decrement(ref pending) == 0)
promise.Resolve(result);
},
e => promise.Reject(e)
);
} else {
if (Interlocked.Decrement(ref pending) == 0)
promise.Resolve(result);
}
cin
refactoring
r25 }
promise.Cancelled(
() => {
cin
removed the reference to the parent from the promise object this allows...
r33 foreach (var d in promises)
if (d != null && d.IsExclusive)
cin
refactoring
r25 d.Cancel();
}
);
return promise;
}
cin
removed the reference to the parent from the promise object this allows...
r33 /// <summary>
/// Объединяет несколько обещаний в одно. Результирующее обещание будет выполнено при
/// выполнении всех указанных обещаний. При этом возвращаемые значения первичных обещаний
/// игнорируются.
/// </summary>
/// <param name="promises">Коллекция первичных обещаний, которые будут объеденены в одно.</param>
/// <returns>Новое обещание, объединяющее в себе переданные.</returns>
/// <remarks>
/// Если в коллекции встречаюься <c>null</c>, то они воспринимаются как выполненные обещания.
/// </remarks>
public static IPromiseBase CreateComposite(ICollection<IPromiseBase> promises) {
if (promises == null)
throw new ArgumentNullException();
if (promises.Count == 0)
return Promise<object>.ResultToPromise(null);
int countdown = promises.Count;
var result = new Promise<object>();
foreach (var d in promises) {
if (d == null) {
if (Interlocked.Decrement(ref countdown) == 0)
result.Resolve(null);
} else {
d.Then(() => {
if (Interlocked.Decrement(ref countdown) == 0)
result.Resolve(null);
});
}
}
result.Cancelled(() => {
foreach (var d in promises)
if (d != null && d.IsExclusive)
d.Cancel();
});
return result;
}
cin
refactoring
r25 public static Promise<T> ResultToPromise(T result) {
var p = new Promise<T>();
p.Resolve(result);
return p;
}
public static Promise<T> ExceptionToPromise(Exception error) {
if (error == null)
throw new ArgumentNullException();
var p = new Promise<T>();
p.Reject(error);
return p;
}
cin
removed the reference to the parent from the promise object this allows...
r33 #region IPromiseBase explicit implementation
IPromiseBase IPromiseBase.Error(ErrorHandler error) {
return Error(error);
}
IPromiseBase IPromiseBase.Anyway(Action handler) {
return Anyway(handler);
}
IPromiseBase IPromiseBase.Finally(Action handler) {
return Finally(handler);
}
IPromiseBase IPromiseBase.Cancelled(Action handler) {
return Cancelled(handler);
}
void IPromiseBase.Join() {
Join();
}
void IPromiseBase.Join(int timeout) {
Join(timeout);
}
#endregion
cin
*refactoring: Promise.Then now returns a new chained promise...
r6 }
cin
small fixes
r2 }