Exemplo n.º 1
0
        /// <summary>
        /// Creates an asynchronous Task object that executes the given critical phase and optional phases in a background thread
        /// and invokes all other callbacks on the UI thread.
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <param name="beforeStart">Invoked on UI thread</param>
        /// <param name="criticalPhase">First phase to run.  Must succeed (by returning <c>true</c> and not throwing an exception) for the optional phases to run.  Invoked on the background thread.</param>
        /// <param name="optionalPhases">Collection of phases that can fail (by throwing an exception) without preventing subsequent phases from running.  Invoked on the background thread.</param>
        /// <param name="fail">Called if the operation is canceled or the critical phase throws an exception.  Invoked on the UI thread.</param>
        /// <param name="succeed">Called if the operation completes successfully without being canceled.  Invoked on the UI thread.</param>
        /// <returns>
        /// Task object that returns <c>false</c> if the operation was canceled by the user or
        /// the critical phase threw an exception; otherwise <c>true</c>.
        /// </returns>
        private IPromise <bool> CreateStageTask(CancellationToken cancellationToken, BeforePromiseHandler <bool> beforeStart, CriticalPhase criticalPhase, IEnumerable <OptionalPhase> optionalPhases, FailurePromiseHandler <bool> fail, SuccessPromiseHandler <bool> succeed)
        {
            return(new SimplePromise(_uiContext)
                   .CancelWith(cancellationToken)
                   .Before(beforeStart)
                   .Fail(fail)
                   .Canceled(promise => fail(promise)) // TODO: Fix warning
                   .Work(delegate(IPromise <bool> promise)
            {
                cancellationToken.Register(() => Logger.Warn("User canceled current operation"));

                if (criticalPhase())
                {
                    foreach (var phase in optionalPhases.TakeWhile(phase => CanContinue(promise)))
                    {
                        phase();
                    }

                    if (CanContinue(promise))
                    {
                        _uiInvoker.InvokeAsync(() => succeed(promise));
                        return;
                    }
                }

                // TODO: How should we handle exceptions here?
                // The rest of the code assumes exceptions are being handled by the plugin runner.
                _uiInvoker.InvokeAsync(() => fail(promise));
            })
                   );
        }
Exemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="action"></param>
        /// <param name="request"></param>
        /// <param name="argumentType"></param>
        /// <param name="returnType"></param>
        /// <returns></returns>
        protected Task <TResult> GetResponseAsync <TResult>(string action, object request, Type argumentType, Type returnType)
        {
            if (Formatter == null)
            {
                throw new ServiceException("Formatter can't be null");
            }

            var actionInfo = _actionManager.GetAction(action);
            var monitor    = AppHost?.Monitor?.GetClientSession();
            var context    = new ClientContext
            {
                Action    = actionInfo,
                Request   = request,
                Formatter = Formatter,
                Monitor   = monitor,
            };

            monitor?.OnInvoking(context);
            ApplyOnInvokingFilter(context);
            var task = Invoker.InvokeAsync(context);

            return(task.ContinueWith(tsk =>
            {
                ApplyOnInvokedFilter(context);
                monitor?.OnInvoked(context);
                if (tsk.Exception != null)
                {
                    throw tsk.Exception.InnerException;
                }

                return context.Result == null
                                        ? default(TResult)
                                        : (TResult)context.Result;
            }));
        }