internal static Task <object> CastToobject <T>(this Task <T> task)
        {
            // Stay on the same thread if we can
            if (task.IsCompleted)
            {
                if (task.IsFaulted)
                {
                    return(TaskHelpers.FromErrors <object>(task.Exception.InnerExceptions));
                }
                if (task.IsCanceled)
                {
                    return(TaskHelpers.Canceled <object>());
                }
                if (task.Status == TaskStatus.RanToCompletion)
                {
                    return(TaskHelpers.FromResult <object>((object)task.Result));
                }
            }

            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>();

            // schedule a synchronous task to cast: no need to worry about sync context or try/catch
            task.ContinueWith(innerTask =>
            {
                if (innerTask.IsFaulted)
                {
                    tcs.SetException(innerTask.Exception.InnerExceptions);
                }
                else if (innerTask.IsCanceled)
                {
                    tcs.SetCanceled();
                }
                else
                {
                    tcs.SetResult((object)innerTask.Result);
                }
            }, TaskContinuationOptions.ExecuteSynchronously);

            return(tcs.Task);
        }
Пример #2
0
        public static Task <object> CastToObject <T>(this Task <T> task)
        {
            if (task.IsCompleted)
            {
                if (task.IsFaulted)
                {
                    return(TaskHelpers.FromErrors <object>(task.Exception.InnerExceptions));
                }
                if (task.IsCanceled)
                {
                    return(TaskHelpers.Canceled <object>());
                }
                if (task.Status == TaskStatus.RanToCompletion)
                {
                    return(TaskHelpers.FromResult((object)task.Result));
                }
            }

            var tcs = new TaskCompletionSource <object>();

            task.ContinueWith(innerTask =>
            {
                if (innerTask.IsFaulted)
                {
                    tcs.SetException(innerTask.Exception.InnerExceptions);
                }
                else if (innerTask.IsCanceled)
                {
                    tcs.SetCanceled();
                }
                else
                {
                    tcs.SetResult(innerTask.Result);
                }
            }, TaskContinuationOptions.ExecuteSynchronously);

            return(tcs.Task);
        }
Пример #3
0
        internal static bool TrySetFromTask <TResult>(this TaskCompletionSource <Task <TResult> > tcs, Task source)
        {
            if (source.Status == TaskStatus.Canceled)
            {
                return(tcs.TrySetCanceled());
            }

            if (source.Status == TaskStatus.Faulted)
            {
                return(tcs.TrySetException(source.Exception.InnerExceptions));
            }

            if (source.Status == TaskStatus.RanToCompletion)
            {
                // Sometimes the source task is Task<Task<TResult>>, and sometimes it's Task<TResult>.
                // The latter usually happens when we're in the middle of a sync-block postback where
                // the continuation is a function which returns Task<TResult> rather than just TResult,
                // but the originating task was itself just Task<TResult>. An example of this can be
                // found in TaskExtensions.CatchImpl().
                Task <Task <TResult> > taskOfTaskOfResult = source as Task <Task <TResult> >;
                if (taskOfTaskOfResult != null)
                {
                    return(tcs.TrySetResult(taskOfTaskOfResult.Result));
                }

                Task <TResult> taskOfResult = source as Task <TResult>;
                if (taskOfResult != null)
                {
                    return(tcs.TrySetResult(taskOfResult));
                }

                return(tcs.TrySetResult(TaskHelpers.FromResult(default(TResult))));
            }

            return(false);
        }
 internal static Task <TOuterResult> Then <TInnerResult, TOuterResult>(this Task <TInnerResult> task, Func <TInnerResult, TOuterResult> continuation, CancellationToken cancellationToken = default(CancellationToken), bool runSynchronously = false)
 {
     return(task.ThenImpl(t => TaskHelpers.FromResult(continuation(t.Result)), cancellationToken, runSynchronously));
 }
 /// <summary>
 /// Calls the given continuation, after the given task has completed, if the task successfully ran
 /// to completion (i.e., was not cancelled and did not fault).
 /// </summary>
 internal static Task <TOuterResult> Then <TOuterResult>(this Task task, Func <TOuterResult> continuation, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(task.ThenImpl(t => TaskHelpers.FromResult(continuation()), cancellationToken));
 }
 // <summary>
 // Calls the given continuation, after the given task has completed, if the task successfully ran
 // to completion (i.e., was not cancelled and did not fault).
 // </summary>
 internal static Task <TOuterResult> Then <TOuterResult>(this Task task, Func <TOuterResult> continuation, CancellationToken cancellationToken = default(CancellationToken), bool runSynchronously = false, bool continueOnCapturedContext = true)
 {
     return(task.ThenImpl(t => TaskHelpers.FromResult(continuation()), cancellationToken, runSynchronously, continueOnCapturedContext));
 }