Mercurial > pub > ImplabNet
changeset 156:97fbbf816844 v2
Promises: SignalXXX methods merged into SignalHandler method.
Components: RunnableComponent In progress
author | cin |
---|---|
date | Mon, 15 Feb 2016 04:22:15 +0300 |
parents | 037df317f126 |
children | 948c015a9011 |
files | Implab.Fx/ControlBoundPromise.cs Implab/AbstractEvent.cs Implab/AbstractPromise.cs Implab/AbstractPromiseT.cs Implab/Components/ExecutionState.cs Implab/Components/IFactory.cs Implab/Components/RunnableComponent.cs Implab/Implab.csproj Implab/JSON/JSONGrammar.cs Implab/JSON/JSONParser.cs Implab/Parsing/AlphabetBase.cs Implab/Parsing/AltToken.cs Implab/Parsing/CDFADefinition.cs Implab/Parsing/CatToken.cs Implab/Parsing/DFABuilder.cs Implab/Parsing/DFADefinitionBase.cs Implab/Parsing/DFAutomaton.cs Implab/Parsing/EDFADefinition.cs Implab/Parsing/EnumAlphabet.cs Implab/SyncContextPromise.cs MonoPlay/Program.cs |
diffstat | 21 files changed, 237 insertions(+), 180 deletions(-) [+] |
line wrap: on
line diff
--- a/Implab.Fx/ControlBoundPromise.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab.Fx/ControlBoundPromise.cs Mon Feb 15 04:22:15 2016 +0300 @@ -12,27 +12,12 @@ m_target = target; } - protected override void SignalSuccess(Promise<T>.HandlerDescriptor handler) { + protected override void SignalHandler(HandlerDescriptor handler, int signal) { if (m_target.InvokeRequired) - m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor>(base.SignalSuccess), handler); - else - base.SignalSuccess(handler); - } - - protected override void SignalCancelled(Promise<T>.HandlerDescriptor handler, Exception reason) { - if (m_target.InvokeRequired) - m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor,Exception>(base.SignalCancelled), handler, reason); + m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor, int>(base.SignalHandler), handler, signal); else - base.SignalCancelled(handler, reason); + base.SignalHandler(handler, signal); } - - protected override void SignalError(Promise<T>.HandlerDescriptor handler, Exception error) { - if (m_target.InvokeRequired) - m_target.BeginInvoke(new Action<Promise<T>.HandlerDescriptor,Exception>(base.SignalError), handler, error); - else - base.SignalError(handler, error); - } - } }
--- a/Implab/AbstractEvent.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/AbstractEvent.cs Mon Feb 15 04:22:15 2016 +0300 @@ -8,9 +8,9 @@ const int UNRESOLVED_SATE = 0; const int TRANSITIONAL_STATE = 1; - const int SUCCEEDED_STATE = 2; - const int REJECTED_STATE = 3; - const int CANCELLED_STATE = 4; + protected const int SUCCEEDED_STATE = 2; + protected const int REJECTED_STATE = 3; + protected const int CANCELLED_STATE = 4; const int CANCEL_NOT_REQUESTED = 0; const int CANCEL_REQUESTING = 1; @@ -22,7 +22,8 @@ Exception m_error; int m_handlersCount; - readonly THandler[] m_handlers = new THandler[RESERVED_HANDLERS_COUNT]; + //readonly THandler[] m_handlers = new THandler[RESERVED_HANDLERS_COUNT]; + THandler[] m_handlers; MTQueue<THandler> m_extraHandlers; int m_handlerPointer = -1; int m_handlersCommited; @@ -60,7 +61,7 @@ protected void EndSetResult() { CompleteTransit(SUCCEEDED_STATE); - OnSuccess(); + Signal(); } @@ -78,14 +79,13 @@ protected void SetError(Exception error) { if (BeginTransit()) { if (error is OperationCanceledException) { + m_error = error.InnerException; CompleteTransit(CANCELLED_STATE); - m_error = error.InnerException; - OnCancelled(); } else { m_error = error is PromiseTransientException ? error.InnerException : error; CompleteTransit(REJECTED_STATE); - OnError(); } + Signal(); } else { WaitTransition(); if (m_state == SUCCEEDED_STATE) @@ -101,22 +101,18 @@ if (BeginTransit()) { m_error = reason; CompleteTransit(CANCELLED_STATE); - OnCancelled(); + Signal(); } } - protected abstract void SignalSuccess(THandler handler); - - protected abstract void SignalError(THandler handler, Exception error); + protected abstract void SignalHandler(THandler handler, int signal); - protected abstract void SignalCancelled(THandler handler, Exception reason); - - void OnSuccess() { + void Signal() { var hp = m_handlerPointer; var slot = hp +1 ; while (slot < m_handlersCommited) { if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { - SignalSuccess(m_handlers[slot]); + SignalHandler(m_handlers[slot], m_state); } hp = m_handlerPointer; slot = hp +1 ; @@ -126,43 +122,7 @@ if (m_extraHandlers != null) { THandler handler; while (m_extraHandlers.TryDequeue(out handler)) - SignalSuccess(handler); - } - } - - void OnError() { - var hp = m_handlerPointer; - var slot = hp +1 ; - while (slot < m_handlersCommited) { - if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { - SignalError(m_handlers[slot],m_error); - } - hp = m_handlerPointer; - slot = hp +1 ; - } - - if (m_extraHandlers != null) { - THandler handler; - while (m_extraHandlers.TryDequeue(out handler)) - SignalError(handler, m_error); - } - } - - void OnCancelled() { - var hp = m_handlerPointer; - var slot = hp +1 ; - while (slot < m_handlersCommited) { - if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) == hp) { - SignalCancelled(m_handlers[slot], m_error); - } - hp = m_handlerPointer; - slot = hp +1 ; - } - - if (m_extraHandlers != null) { - THandler handler; - while (m_extraHandlers.TryDequeue(out handler)) - SignalCancelled(handler, m_error); + SignalHandler(handler, m_state); } } @@ -194,12 +154,15 @@ if (m_state > 1) { // the promise is in the resolved state, just invoke the handler - InvokeHandler(handler); + SignalHandler(handler, m_state); } else { var slot = Interlocked.Increment(ref m_handlersCount) - 1; if (slot < RESERVED_HANDLERS_COUNT) { + if (slot == 0) + Interlocked.CompareExchange(ref m_handlers, new THandler[RESERVED_HANDLERS_COUNT], null); + m_handlers[slot] = handler; while (slot != Interlocked.CompareExchange(ref m_handlersCommited, slot + 1, slot)) { @@ -212,7 +175,7 @@ if (slot < m_handlersCommited) { if (Interlocked.CompareExchange(ref m_handlerPointer, slot, hp) != hp) continue; - InvokeHandler(m_handlers[slot]); + SignalHandler(m_handlers[slot], m_state); } break; } while(true); @@ -233,27 +196,11 @@ // therefore we need to fetch a handler from the queue and execute it // note that fetched handler may be not the one that we have added // even we can fetch no handlers at all :) - InvokeHandler(handler); + SignalHandler(handler, m_state); } } } - protected void InvokeHandler(THandler handler) { - switch (m_state) { - case SUCCEEDED_STATE: - SignalSuccess(handler); - break; - case CANCELLED_STATE: - SignalCancelled(handler, m_error); - break; - case REJECTED_STATE: - SignalError(handler, m_error); - break; - default: - throw new Exception(String.Format("Invalid promise state {0}", m_state)); - } - } - #endregion #region IPromise implementation
--- a/Implab/AbstractPromise.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/AbstractPromise.cs Mon Feb 15 04:22:15 2016 +0300 @@ -71,16 +71,20 @@ #region implemented abstract members of AbstractPromise - protected override void SignalSuccess(HandlerDescriptor handler) { - handler.SignalSuccess(); - } - - protected override void SignalError(HandlerDescriptor handler, Exception error) { - handler.SignalError(error); - } - - protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) { - handler.SignalCancel(reason); + protected override void SignalHandler(HandlerDescriptor handler, int signal) { + switch (signal) { + case SUCCEEDED_STATE: + handler.SignalSuccess(); + break; + case REJECTED_STATE: + handler.SignalError(Error); + break; + case CANCELLED_STATE: + handler.SignalCancel(CancellationReason); + break; + default: + throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal)); + } } protected override Signal GetResolveSignal() {
--- a/Implab/AbstractPromiseT.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/AbstractPromiseT.cs Mon Feb 15 04:22:15 2016 +0300 @@ -175,16 +175,20 @@ return signal; } - protected override void SignalSuccess(HandlerDescriptor handler) { - handler.SignalSuccess(m_result); - } - - protected override void SignalError(HandlerDescriptor handler, Exception error) { - handler.SignalError(error); - } - - protected override void SignalCancelled(HandlerDescriptor handler, Exception reason) { - handler.SignalCancel(reason); + protected override void SignalHandler(HandlerDescriptor handler, int signal) { + switch (signal) { + case SUCCEEDED_STATE: + handler.SignalSuccess(m_result); + break; + case REJECTED_STATE: + handler.SignalError(Error); + break; + case CANCELLED_STATE: + handler.SignalCancel(CancellationReason); + break; + default: + throw new InvalidOperationException(String.Format("Invalid promise signal: {0}", signal)); + } } #endregion
--- a/Implab/Components/ExecutionState.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Components/ExecutionState.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,8 +1,9 @@ namespace Implab.Components { public enum ExecutionState { + Reserved = 0, Uninitialized, - Initial, + Ready, Starting, Running, Stopping,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Components/IFactory.cs Mon Feb 15 04:22:15 2016 +0300 @@ -0,0 +1,8 @@ +using System; + +namespace Implab.Components { + public interface IFactory<out T> { + T Create(); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Implab/Components/RunnableComponent.cs Mon Feb 15 04:22:15 2016 +0300 @@ -0,0 +1,141 @@ +using System; +using Implab.Parsing; + +namespace Implab.Components { + public class RunnableComponent : Disposable, IRunnable, IInitializable { + class Automaton : DFAutomaton<ExecutionState> { + static readonly EDFADefinition<ExecutionState> _dfa; + + static Automaton() { + + var token = Token + .New(ExecutionState.Uninitialized).Optional() // we can skip uninitialized state + .Cat( + Token.New(ExecutionState.Ready) // uninitialized -> initial + .Cat( + Token.New(ExecutionState.Starting) // initial -> starting + .Cat( + Token.New(ExecutionState.Running) // running -> {stopping -> stopped | failed } + .Cat( + Token.New(ExecutionState.Stopping) // running -> stopping + .Cat( + Token.New(ExecutionState.Stopped) // stopping -> stopped + .Or(Token.New(ExecutionState.Failed)) // stopping -> failed + ) + .Or(Token.New(ExecutionState.Failed)) // running -> failed + ) + .Or(Token.New(ExecutionState.Failed)) // starting -> failed + ).EClosure() + ) + .Or(Token.New(ExecutionState.Failed)) // uninitialized->failed + .Cat(Token.New(ExecutionState.Disposed).Tag(0)) // ... -> disposed + ); + + var builder = new DFABuilder(); + token.Accept(builder); + + var _dfa = new EDFADefinition<ExecutionState>(EnumAlphabet<ExecutionState>.FullAlphabet); + builder.BuildDFA(_dfa); // don't optimize dfa to avoid remapping of the alphabet + + } + + public Automaton() : base(_dfa.States, INITIAL_STATE, ExecutionState.Reserved) { + } + + public void MoveTo(ExecutionState state) { + + if (!CanMove((int)state)) + throw new InvalidOperationException(String.Format("Illegal state transition from {0} to {1}", Current, state)); + Move((int)state); + m_context.info = state; + } + + public ExecutionState Current { + get { + return (ExecutionState)m_context.info; + } + } + } + + readonly Automaton m_automaton = new Automaton(); + IPromise m_pending; + Exception m_lastError; + + protected RunnableComponent(bool initialized) { + if (initialized) + m_automaton.MoveTo(ExecutionState.Ready); + else + m_automaton.MoveTo(ExecutionState.Uninitialized); + } + + #region IInitializable implementation + + public void Init() { + + } + + #endregion + + #region IRunnable implementation + + public IPromise Start() { + return Safe.InvokePromise(() => { + Promise promise; + lock (m_automaton) { + if (m_automaton.Current == ExecutionState.Starting) + return m_pending; + m_automaton.MoveTo(ExecutionState.Starting); + m_pending = promise = new Promise(); + } + + var start = Safe.InvokePromise(OnStart); + promise.On(null, null, start.Cancel); + start.On(promise.Resolve, promise.Reject, promise.CancelOperation); + + return promise.Then(() => { + lock(m_automaton) { + m_automaton.MoveTo(ExecutionState.Running); + m_pending = null; + } + + Run(); + }, err => { + if (BeginTransition(RUNNING_REQUIRE)) { + m_lastError = err; + CompleteTransition(FAILED_STATE); + throw new PromiseTransientException(err); + } + throw new OperationCanceledException(); + }, reason => { + throw new OperationCanceledException("The operation was cancelled", reason); + }); + }); + } + + protected virtual IPromise OnStart() { + return Promise.SUCCESS; + } + + protected virtual void Run() { + } + + public IPromise Stop() { + throw new NotImplementedException(); + } + + public ExecutionState State { + get { + throw new NotImplementedException(); + } + } + + public Exception LastError { + get { + throw new NotImplementedException(); + } + } + + #endregion + } +} +
--- a/Implab/Implab.csproj Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Implab.csproj Mon Feb 15 04:22:15 2016 +0300 @@ -182,6 +182,8 @@ <Compile Include="Components\App.cs" /> <Compile Include="Components\IRunnable.cs" /> <Compile Include="Components\ExecutionState.cs" /> + <Compile Include="Components\RunnableComponent.cs" /> + <Compile Include="Components\IFactory.cs" /> </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <ItemGroup />
--- a/Implab/JSON/JSONGrammar.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/JSON/JSONGrammar.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,13 +1,9 @@ using Implab.Parsing; -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Implab.JSON { - internal class JSONGrammar : Grammar<JSONGrammar> { - public enum TokenType : int { + class JSONGrammar : Grammar<JSONGrammar> { + public enum TokenType { None, BeginObject, EndObject,
--- a/Implab/JSON/JSONParser.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/JSON/JSONParser.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,12 +1,7 @@ -using Implab; -using Implab.Parsing; +using Implab.Parsing; using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Implab.JSON { /// <summary> @@ -192,11 +187,10 @@ if (m_memberContext == MemberContext.MemberName) { m_context.info.memberName = (string)tokenValue; break; - } else { - m_elementType = JSONElementType.Value; - m_elementValue = tokenValue; - return true; } + m_elementType = JSONElementType.Value; + m_elementValue = tokenValue; + return true; case JsonTokenType.Number: m_elementType = JSONElementType.Value; m_elementValue = tokenValue;
--- a/Implab/Parsing/AlphabetBase.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/AlphabetBase.cs Mon Feb 15 04:22:15 2016 +0300 @@ -11,7 +11,7 @@ public const int UNCLASSIFIED = 0; int m_nextId = 1; - int[] m_map; + readonly int[] m_map; public int Count { get { return m_nextId; }
--- a/Implab/Parsing/AltToken.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/AltToken.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,9 +1,4 @@ -using Implab; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; namespace Implab.Parsing { public class AltToken: BinaryToken {
--- a/Implab/Parsing/CDFADefinition.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/CDFADefinition.cs Mon Feb 15 04:22:15 2016 +0300 @@ -7,7 +7,7 @@ namespace Implab.Parsing { public class CDFADefinition : DFADefinitionBase { - Alphabet m_alphabet; + readonly Alphabet m_alphabet; public Alphabet Alphabet { get { return m_alphabet; }
--- a/Implab/Parsing/CatToken.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/CatToken.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,9 +1,4 @@ -using Implab; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System; namespace Implab.Parsing { public class CatToken : BinaryToken {
--- a/Implab/Parsing/DFABuilder.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/DFABuilder.cs Mon Feb 15 04:22:15 2016 +0300 @@ -166,7 +166,7 @@ int[] GetStateTags(HashSet<int> state) { Debug.Assert(state != null); - return state.Where(pos => m_ends.ContainsKey(pos)).Select(pos => m_ends[pos]).ToArray(); + return state.Where(m_ends.ContainsKey).Select(pos => m_ends[pos]).ToArray(); } int DefineState(IDFADefinition automa, HashSet<int> state) {
--- a/Implab/Parsing/DFADefinitionBase.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/DFADefinitionBase.cs Mon Feb 15 04:22:15 2016 +0300 @@ -15,7 +15,7 @@ DFAStateDescriptior[] m_statesArray; - public DFADefinitionBase() { + protected DFADefinitionBase() { m_states = new List<DFAStateDescriptior>(); m_states.Add(new DFAStateDescriptior()); @@ -47,7 +47,7 @@ public int AddState(int[] tag) { var index = m_states.Count; - bool final = tag == null || tag.Length == 0 ? false : true; + bool final = tag != null && tag.Length != 0; m_states.Add(new DFAStateDescriptior { final = final, transitions = new int[AlphabetSize], @@ -139,7 +139,7 @@ // строим карты соотвествия оптимальных состояний с оригинальными - var initialState = optimalStates.Where(x => x.Contains(INITIAL_STATE)).Single(); + var initialState = optimalStates.Single(x => x.Contains(INITIAL_STATE)); // карта получения оптимального состояния по соотвествующему ему простому состоянию int[] reveseOptimalMap = new int[m_states.Count]; @@ -184,10 +184,8 @@ foreach (var term in A) { // ищем все переходы класса по символу term var s2 = reveseOptimalMap[ - optimalMap[s].Select(x => m_states[x].transitions[term]) // все элементарные состояния, куда переходит класс s - .Where(x => x != 0) // только допустимые - .FirstOrDefault() // первое допустимое элементарное состояние, если есть - ]; + optimalMap[s].Select(x => m_states[x].transitions[term]).FirstOrDefault(x => x != 0) // первое допустимое элементарное состояние, если есть + ]; HashSet<int> A2; if (!classes.TryGetValue(s2, out A2)) {
--- a/Implab/Parsing/DFAutomaton.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/DFAutomaton.cs Mon Feb 15 04:22:15 2016 +0300 @@ -37,7 +37,7 @@ Debug.Assert(states != null); Debug.Assert(current >= 0 && current < states.Length); m_contextStack.Push(m_context); - m_context. states = states; + m_context.states = states; m_context.current = current; m_context.info = info; } @@ -52,5 +52,10 @@ Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length); m_context.current = m_context.states[m_context.current].transitions[input]; } + + protected bool CanMove(int input) { + Debug.Assert(input > 0 && input < m_context.states[m_context.current].transitions.Length); + return m_context.states[m_context.current].transitions[input] != UNREACHEBLE_STATE; + } } }
--- a/Implab/Parsing/EDFADefinition.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/EDFADefinition.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,20 +1,15 @@ using Implab; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace Implab.Parsing { public class EDFADefinition<T> : DFADefinitionBase where T : struct, IConvertible { - EnumAlphabet<T> m_alphabet; + readonly EnumAlphabet<T> m_alphabet; public EnumAlphabet<T> Alphabet { get { return m_alphabet; } } - public EDFADefinition(EnumAlphabet<T> alphabet) - : base() { + public EDFADefinition(EnumAlphabet<T> alphabet) { Safe.ArgumentNotNull(alphabet, "alphabet"); m_alphabet = alphabet; }
--- a/Implab/Parsing/EnumAlphabet.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/Parsing/EnumAlphabet.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,11 +1,9 @@ -using Implab; -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; namespace Implab.Parsing { /// <summary> @@ -13,10 +11,11 @@ /// </summary> /// <typeparam name="T">Тип перечислений</typeparam> public class EnumAlphabet<T> : AlphabetBase<T> where T : struct, IConvertible { + [SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes")] static readonly T[] _symbols; static readonly EnumAlphabet<T> _fullAlphabet; - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] + [SuppressMessage("Microsoft.Design", "CA1065:DoNotRaiseExceptionsInUnexpectedLocations")] static EnumAlphabet() { if (!typeof(T).IsEnum) throw new InvalidOperationException("Invalid generic parameter, enumeration is required");
--- a/Implab/SyncContextPromise.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/Implab/SyncContextPromise.cs Mon Feb 15 04:22:15 2016 +0300 @@ -10,16 +10,8 @@ m_context = context; } - protected override void SignalSuccess(Promise<T>.HandlerDescriptor handler) { - m_context.Post(x => base.SignalSuccess(handler), null); - } - - protected override void SignalError(Promise<T>.HandlerDescriptor handler, Exception error) { - m_context.Post(x => base.SignalError(handler, error), null); - } - - protected override void SignalCancelled(Promise<T>.HandlerDescriptor handler, Exception reason) { - m_context.Post(x => base.SignalCancelled(handler, reason), null); + protected override void SignalHandler(HandlerDescriptor handler, int signal) { + m_context.Post(x => base.SignalHandler(handler, signal), null); } } }
--- a/MonoPlay/Program.cs Fri Feb 12 16:24:24 2016 +0300 +++ b/MonoPlay/Program.cs Mon Feb 15 04:22:15 2016 +0300 @@ -1,12 +1,5 @@ using System; -using Implab.Diagnostics; -using Implab.Parallels; using Implab; -using System.Collections.Generic; -using System.Collections.Concurrent; -using System.Threading; -using Implab.JSON; -using System.IO; using System.Threading.Tasks; namespace MonoPlay { @@ -27,7 +20,10 @@ } static IPromise<int> DoItem(int x) { - return Promise<int>.FromResult(x + 1); + //return Promise<int>.FromResult(x + 1); + var p = new Promise<int>(); + p.Resolve(x+1); + return p; } static async Task<int> DoWork() {