예제 #1
0
        private ProgressReportingTask <TResult, TProgress> GetAsynchronousResponseWithProgress <TResult, TProgress>(AsyncResults taskCompletionSource, CancellationToken cancellationToken)
        {
            ProgressReportingTask <TResult, TProgress> progressReportingTask = new ProgressReportingTask <TResult, TProgress>(
                progress =>
            {
                object obj;
                while (taskCompletionSource.TryTake(out obj, (int)TimeSpan.FromMinutes(2).TotalMilliseconds, cancellationToken))
                {
                    progress.MakeProgress((TProgress)obj);
                    if (obj is TProgress)
                    {
                        progress.MakeProgress((TProgress)obj);
                    }
                    else if (obj is TResult)
                    {
                        return((TResult)obj);
                    }
                    else
                    {
                        throw new ArgumentException("Cannot process result type of " + taskCompletionSource.GetConsumingEnumerable(cancellationToken).First().GetType());
                    }
                }
                throw new AbandonedMutexException("We did not receive of reply from the server after 2 minutes for transaction " + taskCompletionSource.Id);
            }, cancellationToken, TaskCreationOptions.None);

            progressReportingTask.Start(BackgroundTaskScheduler.OnBackground());
            Task tt = progressReportingTask;

            tt.OnCancelled(
                canceled =>
            {
                Trace.WriteLine("Got some more cancels");
            }, UITaskScheduler.InvokeAsync());                             // bug here - not being called on cancel
            return(progressReportingTask);
        }
예제 #2
0
        /// <summary>
        /// Wires up the given callbacks with the internal implementation of network callbacks. Note this should be called only once
        /// per asyncResult, otherwise data will be lost.
        /// </summary>
        /// <typeparam name="TProgress">The type of data contract that is returned to show progress.</typeparam>
        /// <typeparam name="TResult">The type of data contract returned when the operation completes or fails.</typeparam>
        /// <param name="userCallback">The callback to wire up.</param>
        /// <param name="asyncResults">The <see cref="AsyncResults"/> associated with the current call.</param>
        protected void SetupCallback <TProgress, TResult>(Callback <TProgress, TResult> userCallback, AsyncResults asyncResults)
        {
            ProgressReportingTask <TResult, TProgress> responseWithProgress = GetAsynchronousResponseWithProgress <TResult, TProgress>(asyncResults, userCallback.CancellationToken);

            ((Task)responseWithProgress).OnCancelled(
                canceled =>
            {
                CancelTransaction(asyncResults.Id);
                userCallback.OnCanceled();
            }, userCallback.CanceledScheduler);                             // bug here - not being called on cancel
            Task <TResult> result = responseWithProgress.OnProgress(
                progressData => userCallback.OnProgress(progressData),
                userCallback.ProgressScheduler);

            result.Pipeline(
                finished =>
            {
                if (finished.Result is IFaulted && ((IFaulted)finished.Result).IsFaulted)
                {
                    throw new AggregateException(((IFaulted)finished.Result).Message);
                }

                userCallback.OnCompleted(finished.Result);
            }, userCallback.CompletedScheduler)
            .OnError(
                exception => userCallback.OnError(exception)
                , userCallback.ErrorScheduler);
        }