示例#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
 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);
     }
 }
示例#3
0
 private static void CompleteAsync <T>(DispatchingTaskCompletionSource <T> tcs, IAsyncResult ar, Func <IAsyncResult, T> end)
 {
     try
     {
         tcs.TrySetResult(end(ar));
     }
     catch (OperationCanceledException)
     {
         tcs.TrySetCanceled();
     }
     catch (Exception ex)
     {
         tcs.TrySetException(ex);
     }
 }
示例#4
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);
         }
     });
 }
示例#5
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);
        }
示例#6
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);
        }