• HttpTaskAsyncHandler IHttpAsyncHandler


    
    namespace Microshaoft
    {
        using System;
        using System.Threading.Tasks;
        using System.Web;
        public class HttpTaskAsyncHandler : IHttpAsyncHandler
        {
            public bool IsReusable
            {
                get { return false; }
            }
            public void ProcessRequest(HttpContext context)
            {
                throw new NotSupportedException();
            }
            public Task ProcessRequestAsync(HttpContextBase context)
            {
                // Microshaoft.
                //TaskAsyncHelper.
                return null;
            }
            IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
            {
                Task task = ProcessRequestAsync(new HttpContextWrapper(context));
                var retVal = new TaskWrapperAsyncResult(task, extraData);
                if (task == null)
                {
                    // No task, so just let ASP.NET deal with it
                    return null;
                }
                if (cb != null)
                {
                    // The callback needs the same argument that the Begin method returns, which is our special wrapper, not the original Task.
                    task.ContinueWith(_ => cb(retVal));
                }
                return retVal;
            }
            void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
            {
                if (result == null)
                {
                    throw new ArgumentNullException("result");
                }
                // The End* method doesn't actually perform any actual work, but we do need to maintain two invariants:
                // 1. Make sure the underlying Task actually *is* complete.
                // 2. If the Task encountered an exception, observe it here.
                // (The Wait method handles both of those.)
                var castResult = (TaskWrapperAsyncResult)result;
                castResult.Task.Wait();
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;
        internal sealed class TaskWrapperAsyncResult : IAsyncResult
        {
            internal TaskWrapperAsyncResult(Task task, object asyncState)
            {
                Task = task;
                AsyncState = asyncState;
            }
            public object AsyncState
            {
                get;
                private set;
            }
            public WaitHandle AsyncWaitHandle
            {
                get { return ((IAsyncResult)Task).AsyncWaitHandle; }
            }
            public bool CompletedSynchronously
            {
                get { return ((IAsyncResult)Task).CompletedSynchronously; }
            }
            public bool IsCompleted
            {
                get { return ((IAsyncResult)Task).IsCompleted; }
            }
            public Task Task
            {
                get;
                private set;
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        using System.Linq;
        using System.Reflection;
        using System.Threading;
        using System.Threading.Tasks;
        public static class TaskAsyncHelper
        {
            private static readonly Task _emptyTask = MakeEmpty();
            private static Task MakeEmpty()
            {
                return FromResult<object>(null);
            }
            public static Task Empty
            {
                get
                {
                    return _emptyTask;
                }
            }
            public static TTask Catch<TTask>(this TTask task) where TTask : Task
            {
                if (task != null && task.Status != TaskStatus.RanToCompletion)
                {
                    task.ContinueWith(innerTask =>
                    {
                        var ex = innerTask.Exception;
                        // observe Exception
    #if !WINDOWS_PHONE && !SILVERLIGHT && !NETFX_CORE
                        Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
    #endif
                    }, TaskContinuationOptions.OnlyOnFaulted);
                }
                return task;
            }
            public static TTask Catch<TTask>(this TTask task, Action<Exception> handler) where TTask : Task
            {
                if (task != null && task.Status != TaskStatus.RanToCompletion)
                {
                    task.ContinueWith(innerTask =>
                    {
                        var ex = innerTask.Exception;
                        // observe Exception
    #if !WINDOWS_PHONE && !SILVERLIGHT && !NETFX_CORE
                        Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
    #endif
                        handler(ex);
                    }, TaskContinuationOptions.OnlyOnFaulted);
                }
                return task;
            }
            public static void ContinueWithNotComplete(this Task task, TaskCompletionSource<object> tcs)
            {
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.SetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.SetCanceled();
                    }
                },
                TaskContinuationOptions.NotOnRanToCompletion);
            }
            public static void ContinueWith(this Task task, TaskCompletionSource<object> tcs)
            {
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.TrySetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.TrySetCanceled();
                    }
                    else
                    {
                        tcs.TrySetResult(null);
                    }
                });
            }
            public static void ContinueWith<T>(this Task<T> task, TaskCompletionSource<T> tcs)
            {
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.TrySetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.TrySetCanceled();
                    }
                    else
                    {
                        tcs.TrySetResult(t.Result);
                    }
                });
            }
            /// <summary>
            /// Passes a task returning function into another task returning function so that
            /// it can decide when it starts and returns a task that completes when all are finished
            /// </summary>
            public static Task Interleave<T>(Func<T, Action, Task> before, Func<Task> after, T arg)
            {
                var tcs = new TaskCompletionSource<object>();
                var tasks = new[] {
                                tcs.Task,
                                before(arg, () => after().ContinueWith(tcs))
                            };
                return tasks.Return();
            }
            public static Task Return(this Task[] tasks)
            {
                return Then(tasks, () => { });
            }
            // Then extesions
            public static Task Then(this Task task, Action successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor);
                    default:
                        return RunTask(task, successor);
                }
            }
            public static Task<TResult> Then<TResult>(this Task task, Func<TResult> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor);
                    default:
                        return TaskRunners<object, TResult>.RunTask(task, successor);
                }
            }
            public static Task Then(this Task[] tasks, Action successor)
            {
                if (tasks.Length == 0)
                {
                    return FromMethod(successor);
                }
                var tcs = new TaskCompletionSource<object>();
                Task.Factory.ContinueWhenAll(tasks, completedTasks =>
                {
                    var faulted = completedTasks.FirstOrDefault(t => t.IsFaulted);
                    if (faulted != null)
                    {
                        tcs.SetException(faulted.Exception);
                        return;
                    }
                    var cancelled = completedTasks.FirstOrDefault(t => t.IsCanceled);
                    if (cancelled != null)
                    {
                        tcs.SetCanceled();
                        return;
                    }
                    successor();
                    tcs.SetResult(null);
                });
                return tcs.Task;
            }
            public static Task Then<T1>(this Task task, Action<T1> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1);
                    default:
                        return GenericDelegates<object, object, T1, object>.ThenWithArgs(task, successor, arg1);
                }
            }
            public static Task Then<T1, T2>(this Task task, Action<T1, T2> successor, T1 arg1, T2 arg2)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1, arg2);
                    default:
                        return GenericDelegates<object, object, T1, T2>.ThenWithArgs(task, successor, arg1, arg2);
                }
            }
            public static Task Then<T1>(this Task task, Func<T1, Task> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1).FastUnwrap();
                    default:
                        return GenericDelegates<object, Task, T1, object>.ThenWithArgs(task, successor, arg1)
                                                                         .FastUnwrap();
                }
            }
            public static Task Then<T1, T2>(this Task task, Func<T1, T2, Task> successor, T1 arg1, T2 arg2)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1, arg2).FastUnwrap();
                    default:
                        return GenericDelegates<object, Task, T1, T2>.ThenWithArgs(task, successor, arg1, arg2)
                                                                     .FastUnwrap();
                }
            }
            public static Task<TResult> Then<T, TResult>(this Task<T> task, Func<T, Task<TResult>> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result).FastUnwrap();
                    default:
                        return TaskRunners<T, Task<TResult>>.RunTask(task, t => successor(t.Result))
                                                            .FastUnwrap();
                }
            }
            public static Task<TResult> Then<T, TResult>(this Task<T> task, Func<T, TResult> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result);
                    default:
                        return TaskRunners<T, TResult>.RunTask(task, t => successor(t.Result));
                }
            }
            public static Task<TResult> Then<T, T1, TResult>(this Task<T> task, Func<T, T1, TResult> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result, arg1);
                    default:
                        return GenericDelegates<T, TResult, T1, object>.ThenWithArgs(task, successor, arg1);
                }
            }
            public static Task Then(this Task task, Func<Task> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor).FastUnwrap();
                    default:
                        return TaskRunners<object, Task>.RunTask(task, successor)
                                                        .FastUnwrap();
                }
            }
            public static Task<TResult> Then<TResult>(this Task task, Func<Task<TResult>> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor).FastUnwrap();
                    default:
                        return TaskRunners<object, Task<TResult>>.RunTask(task, successor)
                                                                 .FastUnwrap();
                }
            }
            public static Task Then<TResult>(this Task<TResult> task, Action<TResult> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result);
                    default:
                        return TaskRunners<TResult, object>.RunTask(task, successor);
                }
            }
            public static Task Then<TResult>(this Task<TResult> task, Func<TResult, Task> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result).FastUnwrap();
                    default:
                        return TaskRunners<TResult, Task>.RunTask(task, t => successor(t.Result))
                                                         .FastUnwrap();
                }
            }
            public static Task<TResult> Then<TResult, T1>(this Task<TResult> task, Func<Task<TResult>, T1, Task<TResult>> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task, arg1).FastUnwrap();
                    default:
                        return GenericDelegates<TResult, Task<TResult>, T1, object>.ThenWithArgs(task, successor, arg1)
                                                                                   .FastUnwrap();
                }
            }
            public static Task FastUnwrap(this Task<Task> task)
            {
                var innerTask = (task.Status == TaskStatus.RanToCompletion) ? task.Result : null;
                return innerTask ?? task.Unwrap();
            }
            public static Task<T> FastUnwrap<T>(this Task<Task<T>> task)
            {
                var innerTask = (task.Status == TaskStatus.RanToCompletion) ? task.Result : null;
                return innerTask ?? task.Unwrap();
            }
            public static Task Delay(TimeSpan timeOut)
            {
    #if NETFX_CORE
                return Task.Delay(timeOut);
    #else
                var tcs = new TaskCompletionSource<object>();
                var timer = new Timer(tcs.SetResult,
                null,
                timeOut,
                TimeSpan.FromMilliseconds(-1));
                return tcs.Task.ContinueWith(_ =>
                {
                    timer.Dispose();
                },
                TaskContinuationOptions.ExecuteSynchronously);
    #endif
            }
            public static Task AllSucceeded(this Task[] tasks, Action continuation)
            {
                return AllSucceeded(tasks, _ => continuation());
            }
            public static Task AllSucceeded(this Task[] tasks, Action<Task[]> continuation)
            {
                return Task.Factory.ContinueWhenAll(tasks, _ =>
                {
                    var cancelledTask = tasks.FirstOrDefault(task => task.IsCanceled);
                    if (cancelledTask != null)
                        throw new TaskCanceledException();
                    var allExceptions =
                        tasks.Where(task => task.IsFaulted).SelectMany(task => task.Exception.InnerExceptions).ToList();
                    if (allExceptions.Count > 0)
                    {
                        throw new AggregateException(allExceptions);
                    }
                    continuation(tasks);
                });
            }
            public static Task FromMethod(Action func)
            {
                try
                {
                    func();
                    return Empty;
                }
                catch (Exception ex)
                {
                    return FromError(ex);
                }
            }
            public static Task FromMethod<T1>(Action<T1> func, T1 arg)
            {
                try
                {
                    func(arg);
                    return Empty;
                }
                catch (Exception ex)
                {
                    return FromError(ex);
                }
            }
            public static Task FromMethod<T1, T2>(Action<T1, T2> func, T1 arg1, T2 arg2)
            {
                try
                {
                    func(arg1, arg2);
                    return Empty;
                }
                catch (Exception ex)
                {
                    return FromError(ex);
                }
            }
            public static Task<TResult> FromMethod<TResult>(Func<TResult> func)
            {
                try
                {
                    return FromResult<TResult>(func());
                }
                catch (Exception ex)
                {
                    return FromError<TResult>(ex);
                }
            }
            public static Task<TResult> FromMethod<T1, TResult>(Func<T1, TResult> func, T1 arg)
            {
                try
                {
                    return FromResult<TResult>(func(arg));
                }
                catch (Exception ex)
                {
                    return FromError<TResult>(ex);
                }
            }
            public static Task<TResult> FromMethod<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
            {
                try
                {
                    return FromResult<TResult>(func(arg1, arg2));
                }
                catch (Exception ex)
                {
                    return FromError<TResult>(ex);
                }
            }
            public static Task<T> FromResult<T>(T value)
            {
                var tcs = new TaskCompletionSource<T>();
                tcs.SetResult(value);
                return tcs.Task;
            }
    #if !NETFX_CORE
            public static TaskContinueWithMethod GetContinueWith(Type taskType)
            {
                var continueWith = (from m in taskType.GetMethods()
                                    let methodParameters = m.GetParameters()
                                    where m.Name.Equals("ContinueWith", StringComparison.OrdinalIgnoreCase) &&
                                        methodParameters.Length == 1
                                    let parameter = methodParameters[0]
                                    where parameter.ParameterType.IsGenericType &&
                                    typeof(Func<,>) == parameter.ParameterType.GetGenericTypeDefinition()
                                    select new TaskContinueWithMethod
                                    {
                                        Method = m.MakeGenericMethod(typeof(Task)),
                                        Type = parameter.ParameterType.GetGenericArguments()[0]
                                    })
                    .FirstOrDefault();
                return continueWith;
            }
    #endif
            internal static Task FromError(Exception e)
            {
                var tcs = new TaskCompletionSource<object>();
                tcs.SetException(e);
                return tcs.Task;
            }
            internal static Task<T> FromError<T>(Exception e)
            {
                var tcs = new TaskCompletionSource<T>();
                tcs.SetException(e);
                return tcs.Task;
            }
            private static Task Canceled()
            {
                var tcs = new TaskCompletionSource<object>();
                tcs.SetCanceled();
                return tcs.Task;
            }
            private static Task<T> Canceled<T>()
            {
                var tcs = new TaskCompletionSource<T>();
                tcs.SetCanceled();
                return tcs.Task;
            }
            public class TaskContinueWithMethod
            {
                public MethodInfo Method { get; set; }
                public Type Type { get; set; }
            }
            private static Task RunTask(Task task, Action successor)
            {
                var tcs = new TaskCompletionSource<object>();
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.SetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.SetCanceled();
                    }
                    else
                    {
                        try
                        {
                            successor();
                            tcs.SetResult(null);
                        }
                        catch (Exception ex)
                        {
                            tcs.SetException(ex);
                        }
                    }
                });
                return tcs.Task;
            }
            private static class TaskRunners<T, TResult>
            {
                internal static Task RunTask(Task<T> task, Action<T> successor)
                {
                    var tcs = new TaskCompletionSource<object>();
                    task.ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            tcs.SetException(t.Exception);
                        }
                        else if (t.IsCanceled)
                        {
                            tcs.SetCanceled();
                        }
                        else
                        {
                            try
                            {
                                successor(t.Result);
                                tcs.SetResult(null);
                            }
                            catch (Exception ex)
                            {
                                tcs.SetException(ex);
                            }
                        }
                    });
                    return tcs.Task;
                }
                internal static Task<TResult> RunTask(Task task, Func<TResult> successor)
                {
                    var tcs = new TaskCompletionSource<TResult>();
                    task.ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            tcs.SetException(t.Exception);
                        }
                        else if (t.IsCanceled)
                        {
                            tcs.SetCanceled();
                        }
                        else
                        {
                            try
                            {
                                tcs.SetResult(successor());
                            }
                            catch (Exception ex)
                            {
                                tcs.SetException(ex);
                            }
                        }
                    });
                    return tcs.Task;
                }
                internal static Task<TResult> RunTask(Task<T> task, Func<Task<T>, TResult> successor)
                {
                    var tcs = new TaskCompletionSource<TResult>();
                    task.ContinueWith(t =>
                    {
                        if (task.IsFaulted)
                        {
                            tcs.SetException(t.Exception);
                        }
                        else if (task.IsCanceled)
                        {
                            tcs.SetCanceled();
                        }
                        else
                        {
                            try
                            {
                                tcs.SetResult(successor(t));
                            }
                            catch (Exception ex)
                            {
                                tcs.SetException(ex);
                            }
                        }
                    });
                    return tcs.Task;
                }
            }
            private static class GenericDelegates<T, TResult, T1, T2>
            {
                internal static Task ThenWithArgs(Task task, Action<T1> successor, T1 arg1)
                {
                    return RunTask(task, () => successor(arg1));
                }
                internal static Task ThenWithArgs(Task task, Action<T1, T2> successor, T1 arg1, T2 arg2)
                {
                    return RunTask(task, () => successor(arg1, arg2));
                }
                internal static Task<TResult> ThenWithArgs(Task task, Func<T1, TResult> successor, T1 arg1)
                {
                    return TaskRunners<object, TResult>.RunTask(task, () => successor(arg1));
                }
                internal static Task<TResult> ThenWithArgs(Task task, Func<T1, T2, TResult> successor, T1 arg1, T2 arg2)
                {
                    return TaskRunners<object, TResult>.RunTask(task, () => successor(arg1, arg2));
                }
                internal static Task<TResult> ThenWithArgs(Task<T> task, Func<T, T1, TResult> successor, T1 arg1)
                {
                    return TaskRunners<T, TResult>.RunTask(task, t => successor(t.Result, arg1));
                }
                internal static Task<Task> ThenWithArgs(Task task, Func<T1, Task> successor, T1 arg1)
                {
                    return TaskRunners<object, Task>.RunTask(task, () => successor(arg1));
                }
                internal static Task<Task<TResult>> ThenWithArgs(Task<T> task, Func<T, T1, Task<TResult>> successor, T1 arg1)
                {
                    return TaskRunners<T, Task<TResult>>.RunTask(task, t => successor(t.Result, arg1));
                }
                internal static Task<Task<T>> ThenWithArgs(Task<T> task, Func<Task<T>, T1, Task<T>> successor, T1 arg1)
                {
                    return TaskRunners<T, Task<T>>.RunTask(task, t => successor(t, arg1));
                }
            }
        }
    }
    
    
    
    namespace Microshaoft
    {
        using System;
        using System.Threading.Tasks;
        using System.Web;
        public class HttpTaskAsyncHandler : IHttpAsyncHandler
        {
            public bool IsReusable
            {
                get { return false; }
            }
            public void ProcessRequest(HttpContext context)
            {
                throw new NotSupportedException();
            }
            public Task ProcessRequestAsync(HttpContextBase context)
            {
                // Microshaoft.
                //TaskAsyncHelper.
                return null;
            }
            IAsyncResult IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
            {
                Task task = ProcessRequestAsync(new HttpContextWrapper(context));
                var retVal = new TaskWrapperAsyncResult(task, extraData);
                if (task == null)
                {
                    // No task, so just let ASP.NET deal with it
                    return null;
                }
                if (cb != null)
                {
                    // The callback needs the same argument that the Begin method returns, which is our special wrapper, not the original Task.
                    task.ContinueWith(_ => cb(retVal));
                }
                return retVal;
            }
            void IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
            {
                if (result == null)
                {
                    throw new ArgumentNullException("result");
                }
                // The End* method doesn't actually perform any actual work, but we do need to maintain two invariants:
                // 1. Make sure the underlying Task actually *is* complete.
                // 2. If the Task encountered an exception, observe it here.
                // (The Wait method handles both of those.)
                var castResult = (TaskWrapperAsyncResult)result;
                castResult.Task.Wait();
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;
        internal sealed class TaskWrapperAsyncResult : IAsyncResult
        {
            internal TaskWrapperAsyncResult(Task task, object asyncState)
            {
                Task = task;
                AsyncState = asyncState;
            }
            public object AsyncState
            {
                get;
                private set;
            }
            public WaitHandle AsyncWaitHandle
            {
                get { return ((IAsyncResult)Task).AsyncWaitHandle; }
            }
            public bool CompletedSynchronously
            {
                get { return ((IAsyncResult)Task).CompletedSynchronously; }
            }
            public bool IsCompleted
            {
                get { return ((IAsyncResult)Task).IsCompleted; }
            }
            public Task Task
            {
                get;
                private set;
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        using System.Linq;
        using System.Reflection;
        using System.Threading;
        using System.Threading.Tasks;
        public static class TaskAsyncHelper
        {
            private static readonly Task _emptyTask = MakeEmpty();
            private static Task MakeEmpty()
            {
                return FromResult<object>(null);
            }
            public static Task Empty
            {
                get
                {
                    return _emptyTask;
                }
            }
            public static TTask Catch<TTask>(this TTask task) where TTask : Task
            {
                if (task != null && task.Status != TaskStatus.RanToCompletion)
                {
                    task.ContinueWith(innerTask =>
                    {
                        var ex = innerTask.Exception;
                        // observe Exception
    #if !WINDOWS_PHONE && !SILVERLIGHT && !NETFX_CORE
                        Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
    #endif
                    }, TaskContinuationOptions.OnlyOnFaulted);
                }
                return task;
            }
            public static TTask Catch<TTask>(this TTask task, Action<Exception> handler) where TTask : Task
            {
                if (task != null && task.Status != TaskStatus.RanToCompletion)
                {
                    task.ContinueWith(innerTask =>
                    {
                        var ex = innerTask.Exception;
                        // observe Exception
    #if !WINDOWS_PHONE && !SILVERLIGHT && !NETFX_CORE
                        Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
    #endif
                        handler(ex);
                    }, TaskContinuationOptions.OnlyOnFaulted);
                }
                return task;
            }
            public static void ContinueWithNotComplete(this Task task, TaskCompletionSource<object> tcs)
            {
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.SetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.SetCanceled();
                    }
                },
                TaskContinuationOptions.NotOnRanToCompletion);
            }
            public static void ContinueWith(this Task task, TaskCompletionSource<object> tcs)
            {
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.TrySetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.TrySetCanceled();
                    }
                    else
                    {
                        tcs.TrySetResult(null);
                    }
                });
            }
            public static void ContinueWith<T>(this Task<T> task, TaskCompletionSource<T> tcs)
            {
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.TrySetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.TrySetCanceled();
                    }
                    else
                    {
                        tcs.TrySetResult(t.Result);
                    }
                });
            }
            /// <summary>
            /// Passes a task returning function into another task returning function so that
            /// it can decide when it starts and returns a task that completes when all are finished
            /// </summary>
            public static Task Interleave<T>(Func<T, Action, Task> before, Func<Task> after, T arg)
            {
                var tcs = new TaskCompletionSource<object>();
                var tasks = new[] {
                                tcs.Task,
                                before(arg, () => after().ContinueWith(tcs))
                            };
                return tasks.Return();
            }
            public static Task Return(this Task[] tasks)
            {
                return Then(tasks, () => { });
            }
            // Then extesions
            public static Task Then(this Task task, Action successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor);
                    default:
                        return RunTask(task, successor);
                }
            }
            public static Task<TResult> Then<TResult>(this Task task, Func<TResult> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor);
                    default:
                        return TaskRunners<object, TResult>.RunTask(task, successor);
                }
            }
            public static Task Then(this Task[] tasks, Action successor)
            {
                if (tasks.Length == 0)
                {
                    return FromMethod(successor);
                }
                var tcs = new TaskCompletionSource<object>();
                Task.Factory.ContinueWhenAll(tasks, completedTasks =>
                {
                    var faulted = completedTasks.FirstOrDefault(t => t.IsFaulted);
                    if (faulted != null)
                    {
                        tcs.SetException(faulted.Exception);
                        return;
                    }
                    var cancelled = completedTasks.FirstOrDefault(t => t.IsCanceled);
                    if (cancelled != null)
                    {
                        tcs.SetCanceled();
                        return;
                    }
                    successor();
                    tcs.SetResult(null);
                });
                return tcs.Task;
            }
            public static Task Then<T1>(this Task task, Action<T1> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1);
                    default:
                        return GenericDelegates<object, object, T1, object>.ThenWithArgs(task, successor, arg1);
                }
            }
            public static Task Then<T1, T2>(this Task task, Action<T1, T2> successor, T1 arg1, T2 arg2)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1, arg2);
                    default:
                        return GenericDelegates<object, object, T1, T2>.ThenWithArgs(task, successor, arg1, arg2);
                }
            }
            public static Task Then<T1>(this Task task, Func<T1, Task> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1).FastUnwrap();
                    default:
                        return GenericDelegates<object, Task, T1, object>.ThenWithArgs(task, successor, arg1)
                                                                         .FastUnwrap();
                }
            }
            public static Task Then<T1, T2>(this Task task, Func<T1, T2, Task> successor, T1 arg1, T2 arg2)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, arg1, arg2).FastUnwrap();
                    default:
                        return GenericDelegates<object, Task, T1, T2>.ThenWithArgs(task, successor, arg1, arg2)
                                                                     .FastUnwrap();
                }
            }
            public static Task<TResult> Then<T, TResult>(this Task<T> task, Func<T, Task<TResult>> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result).FastUnwrap();
                    default:
                        return TaskRunners<T, Task<TResult>>.RunTask(task, t => successor(t.Result))
                                                            .FastUnwrap();
                }
            }
            public static Task<TResult> Then<T, TResult>(this Task<T> task, Func<T, TResult> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result);
                    default:
                        return TaskRunners<T, TResult>.RunTask(task, t => successor(t.Result));
                }
            }
            public static Task<TResult> Then<T, T1, TResult>(this Task<T> task, Func<T, T1, TResult> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result, arg1);
                    default:
                        return GenericDelegates<T, TResult, T1, object>.ThenWithArgs(task, successor, arg1);
                }
            }
            public static Task Then(this Task task, Func<Task> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor).FastUnwrap();
                    default:
                        return TaskRunners<object, Task>.RunTask(task, successor)
                                                        .FastUnwrap();
                }
            }
            public static Task<TResult> Then<TResult>(this Task task, Func<Task<TResult>> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor).FastUnwrap();
                    default:
                        return TaskRunners<object, Task<TResult>>.RunTask(task, successor)
                                                                 .FastUnwrap();
                }
            }
            public static Task Then<TResult>(this Task<TResult> task, Action<TResult> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result);
                    default:
                        return TaskRunners<TResult, object>.RunTask(task, successor);
                }
            }
            public static Task Then<TResult>(this Task<TResult> task, Func<TResult, Task> successor)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task.Result).FastUnwrap();
                    default:
                        return TaskRunners<TResult, Task>.RunTask(task, t => successor(t.Result))
                                                         .FastUnwrap();
                }
            }
            public static Task<TResult> Then<TResult, T1>(this Task<TResult> task, Func<Task<TResult>, T1, Task<TResult>> successor, T1 arg1)
            {
                switch (task.Status)
                {
                    case TaskStatus.Faulted:
                        return FromError<TResult>(task.Exception);
                    case TaskStatus.Canceled:
                        return Canceled<TResult>();
                    case TaskStatus.RanToCompletion:
                        return FromMethod(successor, task, arg1).FastUnwrap();
                    default:
                        return GenericDelegates<TResult, Task<TResult>, T1, object>.ThenWithArgs(task, successor, arg1)
                                                                                   .FastUnwrap();
                }
            }
            public static Task FastUnwrap(this Task<Task> task)
            {
                var innerTask = (task.Status == TaskStatus.RanToCompletion) ? task.Result : null;
                return innerTask ?? task.Unwrap();
            }
            public static Task<T> FastUnwrap<T>(this Task<Task<T>> task)
            {
                var innerTask = (task.Status == TaskStatus.RanToCompletion) ? task.Result : null;
                return innerTask ?? task.Unwrap();
            }
            public static Task Delay(TimeSpan timeOut)
            {
    #if NETFX_CORE
                return Task.Delay(timeOut);
    #else
                var tcs = new TaskCompletionSource<object>();
                var timer = new Timer(tcs.SetResult,
                null,
                timeOut,
                TimeSpan.FromMilliseconds(-1));
                return tcs.Task.ContinueWith(_ =>
                {
                    timer.Dispose();
                },
                TaskContinuationOptions.ExecuteSynchronously);
    #endif
            }
            public static Task AllSucceeded(this Task[] tasks, Action continuation)
            {
                return AllSucceeded(tasks, _ => continuation());
            }
            public static Task AllSucceeded(this Task[] tasks, Action<Task[]> continuation)
            {
                return Task.Factory.ContinueWhenAll(tasks, _ =>
                {
                    var cancelledTask = tasks.FirstOrDefault(task => task.IsCanceled);
                    if (cancelledTask != null)
                        throw new TaskCanceledException();
                    var allExceptions =
                        tasks.Where(task => task.IsFaulted).SelectMany(task => task.Exception.InnerExceptions).ToList();
                    if (allExceptions.Count > 0)
                    {
                        throw new AggregateException(allExceptions);
                    }
                    continuation(tasks);
                });
            }
            public static Task FromMethod(Action func)
            {
                try
                {
                    func();
                    return Empty;
                }
                catch (Exception ex)
                {
                    return FromError(ex);
                }
            }
            public static Task FromMethod<T1>(Action<T1> func, T1 arg)
            {
                try
                {
                    func(arg);
                    return Empty;
                }
                catch (Exception ex)
                {
                    return FromError(ex);
                }
            }
            public static Task FromMethod<T1, T2>(Action<T1, T2> func, T1 arg1, T2 arg2)
            {
                try
                {
                    func(arg1, arg2);
                    return Empty;
                }
                catch (Exception ex)
                {
                    return FromError(ex);
                }
            }
            public static Task<TResult> FromMethod<TResult>(Func<TResult> func)
            {
                try
                {
                    return FromResult<TResult>(func());
                }
                catch (Exception ex)
                {
                    return FromError<TResult>(ex);
                }
            }
            public static Task<TResult> FromMethod<T1, TResult>(Func<T1, TResult> func, T1 arg)
            {
                try
                {
                    return FromResult<TResult>(func(arg));
                }
                catch (Exception ex)
                {
                    return FromError<TResult>(ex);
                }
            }
            public static Task<TResult> FromMethod<T1, T2, TResult>(Func<T1, T2, TResult> func, T1 arg1, T2 arg2)
            {
                try
                {
                    return FromResult<TResult>(func(arg1, arg2));
                }
                catch (Exception ex)
                {
                    return FromError<TResult>(ex);
                }
            }
            public static Task<T> FromResult<T>(T value)
            {
                var tcs = new TaskCompletionSource<T>();
                tcs.SetResult(value);
                return tcs.Task;
            }
    #if !NETFX_CORE
            public static TaskContinueWithMethod GetContinueWith(Type taskType)
            {
                var continueWith = (from m in taskType.GetMethods()
                                    let methodParameters = m.GetParameters()
                                    where m.Name.Equals("ContinueWith", StringComparison.OrdinalIgnoreCase) &&
                                        methodParameters.Length == 1
                                    let parameter = methodParameters[0]
                                    where parameter.ParameterType.IsGenericType &&
                                    typeof(Func<,>) == parameter.ParameterType.GetGenericTypeDefinition()
                                    select new TaskContinueWithMethod
                                    {
                                        Method = m.MakeGenericMethod(typeof(Task)),
                                        Type = parameter.ParameterType.GetGenericArguments()[0]
                                    })
                    .FirstOrDefault();
                return continueWith;
            }
    #endif
            internal static Task FromError(Exception e)
            {
                var tcs = new TaskCompletionSource<object>();
                tcs.SetException(e);
                return tcs.Task;
            }
            internal static Task<T> FromError<T>(Exception e)
            {
                var tcs = new TaskCompletionSource<T>();
                tcs.SetException(e);
                return tcs.Task;
            }
            private static Task Canceled()
            {
                var tcs = new TaskCompletionSource<object>();
                tcs.SetCanceled();
                return tcs.Task;
            }
            private static Task<T> Canceled<T>()
            {
                var tcs = new TaskCompletionSource<T>();
                tcs.SetCanceled();
                return tcs.Task;
            }
            public class TaskContinueWithMethod
            {
                public MethodInfo Method { get; set; }
                public Type Type { get; set; }
            }
            private static Task RunTask(Task task, Action successor)
            {
                var tcs = new TaskCompletionSource<object>();
                task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        tcs.SetException(t.Exception);
                    }
                    else if (t.IsCanceled)
                    {
                        tcs.SetCanceled();
                    }
                    else
                    {
                        try
                        {
                            successor();
                            tcs.SetResult(null);
                        }
                        catch (Exception ex)
                        {
                            tcs.SetException(ex);
                        }
                    }
                });
                return tcs.Task;
            }
            private static class TaskRunners<T, TResult>
            {
                internal static Task RunTask(Task<T> task, Action<T> successor)
                {
                    var tcs = new TaskCompletionSource<object>();
                    task.ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            tcs.SetException(t.Exception);
                        }
                        else if (t.IsCanceled)
                        {
                            tcs.SetCanceled();
                        }
                        else
                        {
                            try
                            {
                                successor(t.Result);
                                tcs.SetResult(null);
                            }
                            catch (Exception ex)
                            {
                                tcs.SetException(ex);
                            }
                        }
                    });
                    return tcs.Task;
                }
                internal static Task<TResult> RunTask(Task task, Func<TResult> successor)
                {
                    var tcs = new TaskCompletionSource<TResult>();
                    task.ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            tcs.SetException(t.Exception);
                        }
                        else if (t.IsCanceled)
                        {
                            tcs.SetCanceled();
                        }
                        else
                        {
                            try
                            {
                                tcs.SetResult(successor());
                            }
                            catch (Exception ex)
                            {
                                tcs.SetException(ex);
                            }
                        }
                    });
                    return tcs.Task;
                }
                internal static Task<TResult> RunTask(Task<T> task, Func<Task<T>, TResult> successor)
                {
                    var tcs = new TaskCompletionSource<TResult>();
                    task.ContinueWith(t =>
                    {
                        if (task.IsFaulted)
                        {
                            tcs.SetException(t.Exception);
                        }
                        else if (task.IsCanceled)
                        {
                            tcs.SetCanceled();
                        }
                        else
                        {
                            try
                            {
                                tcs.SetResult(successor(t));
                            }
                            catch (Exception ex)
                            {
                                tcs.SetException(ex);
                            }
                        }
                    });
                    return tcs.Task;
                }
            }
            private static class GenericDelegates<T, TResult, T1, T2>
            {
                internal static Task ThenWithArgs(Task task, Action<T1> successor, T1 arg1)
                {
                    return RunTask(task, () => successor(arg1));
                }
                internal static Task ThenWithArgs(Task task, Action<T1, T2> successor, T1 arg1, T2 arg2)
                {
                    return RunTask(task, () => successor(arg1, arg2));
                }
                internal static Task<TResult> ThenWithArgs(Task task, Func<T1, TResult> successor, T1 arg1)
                {
                    return TaskRunners<object, TResult>.RunTask(task, () => successor(arg1));
                }
                internal static Task<TResult> ThenWithArgs(Task task, Func<T1, T2, TResult> successor, T1 arg1, T2 arg2)
                {
                    return TaskRunners<object, TResult>.RunTask(task, () => successor(arg1, arg2));
                }
                internal static Task<TResult> ThenWithArgs(Task<T> task, Func<T, T1, TResult> successor, T1 arg1)
                {
                    return TaskRunners<T, TResult>.RunTask(task, t => successor(t.Result, arg1));
                }
                internal static Task<Task> ThenWithArgs(Task task, Func<T1, Task> successor, T1 arg1)
                {
                    return TaskRunners<object, Task>.RunTask(task, () => successor(arg1));
                }
                internal static Task<Task<TResult>> ThenWithArgs(Task<T> task, Func<T, T1, Task<TResult>> successor, T1 arg1)
                {
                    return TaskRunners<T, Task<TResult>>.RunTask(task, t => successor(t.Result, arg1));
                }
                internal static Task<Task<T>> ThenWithArgs(Task<T> task, Func<Task<T>, T1, Task<T>> successor, T1 arg1)
                {
                    return TaskRunners<T, Task<T>>.RunTask(task, t => successor(t, arg1));
                }
            }
        }
    }
    
    
  • 相关阅读:
    设计模式之中介者模式
    解释器模式(行为模式)
    进程池Pool
    Process子类
    multiprocessing
    random
    re
    time和datetime
    logging 日志
    hashlib
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2557141.html
Copyright © 2020-2023  润新知