예제 #1
0
        private Task ExecuteHubEvent(IRequest request, string connectionId, Func <IHub, Task> action)
        {
            var hubs       = GetHubs(request, connectionId).ToList();
            var operations = hubs.Select(instance => action(instance).OrEmpty().Catch(Trace)).ToArray();

            if (operations.Length == 0)
            {
                DisposeHubs(hubs);
                return(TaskAsyncHelper.Empty);
            }

            var tcs = new DispatchingTaskCompletionSource <object>();

            Task.Factory.ContinueWhenAll(operations, tasks =>
            {
                DisposeHubs(hubs);
                var faulted = tasks.FirstOrDefault(t => t.IsFaulted);
                if (faulted != null)
                {
                    tcs.TrySetUnwrappedException(faulted.Exception);
                }
                else if (tasks.Any(t => t.IsCanceled))
                {
                    tcs.TrySetCanceled();
                }
                else
                {
                    tcs.TrySetResult(null);
                }
            });

            return(tcs.Task);
        }
예제 #2
0
            public void Complete()
            {
                _transport.ApplyState(TransportConnectionStates.HttpRequestEnded);

                if (_error != null)
                {
                    _lifetimeTcs.TrySetUnwrappedException(_error);
                }
                else
                {
                    _lifetimeTcs.TrySetResult(null);
                }
            }
예제 #3
0
        internal static Task <object> Incoming(IHubIncomingInvokerContext context)
        {
            var tcs = new DispatchingTaskCompletionSource <object>();

            try
            {
                object result     = context.MethodDescriptor.Invoker(context.Hub, context.Args.ToArray());
                Type   returnType = context.MethodDescriptor.ReturnType;

                if (typeof(Task).IsAssignableFrom(returnType))
                {
                    var task = (Task)result;
                    if (!returnType.IsGenericType)
                    {
                        task.ContinueWith(tcs);
                    }
                    else
                    {
                        // Get the <T> in Task<T>
                        Type resultType = returnType.GetGenericArguments().Single();

                        Type genericTaskType = typeof(Task <>).MakeGenericType(resultType);

                        // Get the correct ContinueWith overload
                        var parameter = Expression.Parameter(typeof(object));

                        // TODO: Cache this whole thing
                        // Action<object> callback = result => ContinueWith((Task<T>)result, tcs);
                        MethodInfo continueWithMethod = _continueWithMethod.MakeGenericMethod(resultType);

                        Expression body = Expression.Call(continueWithMethod,
                                                          Expression.Convert(parameter, genericTaskType),
                                                          Expression.Constant(tcs));

                        var continueWithInvoker = Expression.Lambda <Action <object> >(body, parameter).Compile();
                        continueWithInvoker.Invoke(result);
                    }
                }
                else
                {
                    tcs.TrySetResult(result);
                }
            }
            catch (Exception ex)
            {
                tcs.TrySetUnwrappedException(ex);
            }

            return(tcs.Task);
        }
예제 #4
0
 private static void ContinueSync <T>(Task <T> task, DispatchingTaskCompletionSource <object> tcs)
 {
     if (task.IsFaulted)
     {
         tcs.TrySetUnwrappedException(task.Exception);
     }
     else if (task.IsCanceled)
     {
         tcs.TrySetCanceled();
     }
     else
     {
         tcs.TrySetResult(task.Result);
     }
 }
예제 #5
0
 private static void ContinueAsync <T>(Task <T> task, DispatchingTaskCompletionSource <object> tcs)
 {
     task.ContinueWithPreservedCulture(t =>
     {
         if (t.IsFaulted)
         {
             tcs.TrySetUnwrappedException(t.Exception);
         }
         else if (t.IsCanceled)
         {
             tcs.TrySetCanceled();
         }
         else
         {
             tcs.TrySetResult(t.Result);
         }
     });
 }
        private void CompleteFail(Exception ex)
        {
            var previousState = Interlocked.Exchange(ref _state, InitializationState.Failed);

            Dispatch(() =>
            {
                OnFailure();

                // if the transport failed during start request we want to fail with StartException
                // so that AutoTransport does not try other transports
                if (previousState == InitializationState.AfterConnect && !(ex is StartException))
                {
                    ex = new StartException(Resources.Error_StartFailed, ex);
                }

                _initializationTask.TrySetUnwrappedException(ex);
            });

            if (_tokenCleanup != null)
            {
                _tokenCleanup.Dispose();
            }
        }
예제 #7
0
        public Task <TResult> Invoke <TResult, TProgress>(string method, Action <TProgress> onProgress, params object[] args)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            var tokenifiedArguments = new JToken[args.Length];

            for (int i = 0; i < tokenifiedArguments.Length; i++)
            {
                tokenifiedArguments[i] = args[i] != null
                    ? JToken.FromObject(args[i], JsonSerializer)
                    : JValue.CreateNull();
            }

            var tcs        = new DispatchingTaskCompletionSource <TResult>();
            var callbackId = _connection.RegisterCallback(result =>
            {
                if (result != null)
                {
                    if (result.Error != null)
                    {
                        if (result.IsHubException.HasValue && result.IsHubException.Value)
                        {
                            // A HubException was thrown
                            tcs.TrySetException(new HubException(result.Error, result.ErrorData));
                        }
                        else
                        {
                            tcs.TrySetException(new InvalidOperationException(result.Error));
                        }
                    }
                    else
                    {
                        try
                        {
                            if (result.State != null)
                            {
                                foreach (var pair in result.State)
                                {
                                    this[pair.Key] = pair.Value;
                                }
                            }

                            if (result.ProgressUpdate != null)
                            {
                                onProgress(result.ProgressUpdate.Data.ToObject <TProgress>(JsonSerializer));
                            }
                            else if (result.Result != null)
                            {
                                tcs.TrySetResult(result.Result.ToObject <TResult>(JsonSerializer));
                            }
                            else
                            {
                                tcs.TrySetResult(default(TResult));
                            }
                        }
                        catch (Exception ex)
                        {
                            // If we failed to set the result for some reason or to update
                            // state then just fail the tcs.
                            tcs.TrySetUnwrappedException(ex);
                        }
                    }
                }
                else
                {
                    tcs.TrySetCanceled();
                }
            });

            var hubData = new HubInvocation
            {
                Hub        = _hubName,
                Method     = method,
                Args       = tokenifiedArguments,
                CallbackId = callbackId
            };

            if (_state.Count != 0)
            {
                hubData.State = _state;
            }

            var value = _connection.JsonSerializeObject(hubData);

            _connection.Send(value).ContinueWith(task =>
            {
                if (task.IsCanceled)
                {
                    _connection.RemoveCallback(callbackId);
                    tcs.TrySetCanceled();
                }
                else if (task.IsFaulted)
                {
                    _connection.RemoveCallback(callbackId);
                    tcs.TrySetUnwrappedException(task.Exception);
                }
            },
                                                 TaskContinuationOptions.NotOnRanToCompletion);

            return(tcs.Task);
        }
예제 #8
0
        public Task <JSONNode> Invoke(string method, Action <JSONNode> onProgress, params object[] args)
        {
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            if (args == null)
            {
                throw new ArgumentNullException("args");
            }

            JSONArray ArgsArray = new JSONArray();

            for (int i = 0; i < args.Length; i++)
            {
                ArgsArray.Add(JSON.FromData(args[i]));
            }

            var tcs        = new DispatchingTaskCompletionSource <JSONNode>();
            var callbackId = _connection.RegisterCallback(result =>
            {
                if (result != null)
                {
                    if (result.Error != null)
                    {
                        if (result.IsHubException)
                        {
                            // A HubException was thrown
                            tcs.TrySetException(new HubException(result.Error, result.ErrorData));
                        }
                        else
                        {
                            tcs.TrySetException(new InvalidOperationException(result.Error));
                        }
                    }
                    else
                    {
                        try
                        {
                            if (result.State != null)
                            {
                                foreach (var pair in result.State)
                                {
                                    this[pair.Key] = pair.Value;
                                }
                            }

                            if (result.ProgressUpdate != null)
                            {
                                onProgress?.Invoke(result.ProgressUpdate.Data);
                            }
                            else if (result.Result != null)
                            {
                                tcs.TrySetResult(result.Result);
                            }
                            else
                            {
                                tcs.TrySetResult(new JSONNonexistent());
                            }
                        }
                        catch (Exception ex)
                        {
                            // If we failed to set the result for some reason or to update
                            // state then just fail the tcs.
                            tcs.TrySetUnwrappedException(ex);
                        }
                    }
                }
                else
                {
                    tcs.TrySetCanceled();
                }
            });

            var hubData = new HubInvocation
            {
                Hub        = _hubName,
                Method     = method,
                Args       = ArgsArray,
                CallbackId = callbackId
            };

            if (_state.Count != 0)
            {
                hubData.State = _state;
            }

            var value = hubData.ToJson().Serialize();

            _connection.Send(value).ContinueWith(task =>
            {
                if (task.IsCanceled)
                {
                    _connection.RemoveCallback(callbackId);
                    tcs.TrySetCanceled();
                }
                else if (task.IsFaulted)
                {
                    _connection.RemoveCallback(callbackId);
                    tcs.TrySetUnwrappedException(task.Exception);
                }
            },
                                                 TaskContinuationOptions.NotOnRanToCompletion);

            return(tcs.Task);
        }