Skip to content

Latest commit

 

History

History
74 lines (63 loc) · 2.26 KB

TaskRunner.md

File metadata and controls

74 lines (63 loc) · 2.26 KB

DevLabs - by Kannan Sundararajan

###Task Runner

ITaskRunner interface so that we can unit test easily

public interface ITaskRunner
{
    Task RunTask<T>(Func<T> task, Action<T> onTaskComplete, Action<IList<Exception>> onException);

    Task RunTask<T, TResult>(Func<T, TResult> task, T taskParameter, Action<TResult> onTaskComplete,
            Action<IList<Exception>> onException);
}

Concrete implementation of the Task runner

public class TaskRunner : ITaskRunner
{
    public  Task RunTask<T, TResult>(Func<T, TResult> task, T taskParameter, Action<TResult> onTaskComplete, Action<IList<Exception>> onException)
    {
        return ContinueTask(Task.Factory.StartNew(() => task(taskParameter)), onTaskComplete, onException);
    }

    public Task RunTask<T>(Func<T> task, Action<T> onTaskComplete, Action<IList<Exception>> onException)
    {
       return ContinueTask(Task.Factory.StartNew(task), onTaskComplete, onException);
    }

    private static Task ContinueTask<T>(Task<T> task, Action<T> onTaskComplete, Action<IList<Exception>> onException)
    {
        var t = task.ContinueWith(
            completedTask =>
            {
                if (completedTask.Exception != null)
                {
                    onException(completedTask.Exception.Flatten().InnerExceptions);
                }
                else
                {
                    try
                    {
                        onTaskComplete(completedTask.Result);
                    }
                    catch (Exception exception)
                    {
                       //TODO: Exclude exceptions that should not be handled by user code
                       //TODO: Maybe we can add extension method to Exception to filter here 
                       //TODO: and re-throw if shouldn't be handled
        
                        onException(new[] { exception });
                    }
                }
            },
            GetSynchronizationContext());
        return t;
    }
    
    private static TaskScheduler GetSynchronizationContext()
    {
        try
        {
            return TaskScheduler.FromCurrentSynchronizationContext();
        }
        catch (InvalidOperationException)
        {
            return TaskScheduler.Default;
        }
    }

}