private Task <TResult> GetAsynchronousResponse <TResult>(AsyncResults taskCompletionSource, CancellationToken cancellationToken) { return(TaskFactoryHelper <TResult> .StartNew( () => { object obj; while (!(taskCompletionSource.TryTake(out obj, (int)TimeSpan.FromMinutes(2).TotalMilliseconds, cancellationToken))) { if (obj is TResult) { return (TResult)obj; } } throw new AbandonedMutexException("We did not receive of reply from the server after 2 minutes for transaction " + taskCompletionSource.Id); }, BackgroundTaskScheduler.OnBackground(), cancellationToken)); }
/// <summary> /// Provides a synchronous wait version of a server request and callback. /// If the caller thread is UI thread, it executes asynchronously. /// If the caller thread is not UI thread, it blocks the caller thread. /// </summary> /// <typeparam name="T">The type expected via callback.</typeparam> /// <typeparam name="TResponse"></typeparam> /// <typeparam name="TRequest"></typeparam> /// <param name="request"></param> /// <param name="svcGatewayMethod"></param> /// <param name="timeout">The time to wait before giving up on the service response.</param> /// <returns></returns> /// <remarks>Note that this does not currently support progress reporting. If the service provides progress /// reports this will need to be amended.</remarks> protected TResponse ServerRequest <TResponse, TRequest>(TRequest request, SvcGatewayDelegate <TRequest, TResponse> svcGatewayMethod, TimeSpan timeout) where TResponse : ServiceResponse where TRequest : ICommonRequest { AsyncResults asyncResults = AddToResponseQueue(request.RequestID); TimeSpan defaultTimeout = TimeSpan.FromMinutes(2); if (defaultTimeout < timeout) { timeout = defaultTimeout; } if (UIThreadSingleton.IsCreated && UIThreadSingleton.IsCallFromUIThread) { Task <TResponse> callCompleted = TaskFactoryHelper <TResponse> .StartNew( () => ExecServerRequest(request, svcGatewayMethod, timeout, asyncResults), BackgroundTaskScheduler.OnBackground()); while (!callCompleted.IsFinishedRunning()) { Application.DoEvents(); } if (callCompleted.Status != TaskStatus.RanToCompletion) { if (callCompleted.Exception != null) { AggregateException aggregateException = callCompleted.Exception.Flatten(); if (aggregateException.InnerException != null) { throw aggregateException.InnerException; } } } return(callCompleted.Result); } else { return(ExecServerRequest(request, svcGatewayMethod, timeout, asyncResults)); } }