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); }
public void Complete() { _transport.ApplyState(TransportConnectionStates.HttpRequestEnded); if (_error != null) { _lifetimeTcs.TrySetUnwrappedException(_error); } else { _lifetimeTcs.TrySetResult(null); } }
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); }
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); } }
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(); } }
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); }
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); }