将通用Action <t>委托调整为非通用Action委托

时间:2017-11-05 23:12:19

标签: c# .net multithreading task-parallel-library

我有一个关于如何将通用Action<T>委托适当地简化为Action委托的简单非通用版本的问题。非通用Action委托实例将用作Task类中的构造函数参数。 要调用的根函数是TaskUtils.ExecuteAction(Action action, bool isAsync = true)

我有一段代码。我希望你能指出我的错误或建议其他一些方法来实施。我对捕获方法参数的上下文存在疑问

public static class TaskUtils
{
    /// <summary>
    /// Executes ACTION delegate
    /// </summary>
    /// <param name="action"></param>
    /// <param name="isAsync"></param>
    /// <returns></returns>
    public static Task ExecuteAction(Action action, bool isAsync = true)
    {
        // validate action delegate
        Action execAction = Ensure.ArgumentNotNull(action, nameof(action), "Action delegate is not set (NULL)");

        if (!isAsync)
        {
            // do action execute
            try
            {
                execAction();
                return Task.CompletedTask;
            } catch (Exception ex)
            {
                // failed handler
                return Task.FromException(ex);
            }
        }

        // run a task in the system thread-pool
        return Task.Run(action, CancellationToken.None);
    }

    /// <summary>
    ///  Adapter function to fit ACTION delegte
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="action"></param>
    /// <param name="arg"></param>
    /// <returns></returns>
    public static Action AdaptToRootAction<T>(Action<T> action, T arg)
    {
        // copy param
        T param = arg;

        return delegate
        {
            // pass parameter 
            // and invoke ACTION
            action(param);
        };
    }

    public static Action AdaptToRootAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2)
    {
        T1 param1 = arg1;
        T2 param2 = arg2;

        return delegate
        {
            // pass two generic parameters
            // and invoke ACTION delegate
            action(param1, param2);
        };
    }

    public static Action AdaptToRootAction<T1, T2, T3>(Action<T1, T2, T3> action, T1 arg1, T2 arg2, T3 arg3)
    {
        T1 param1 = arg1;
        T2 param2 = arg2;
        T3 param3 = arg3;

        return delegate
        {
            // pass three generic parameters
            // and invoke ACTION delegate
            action(param1, param2, param3);
        };
    }

    /// <summary>
    /// Executes a generic <see cref="Action{T}"/> with a passed value of type <typeparam name="T"></typeparam>
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="action"></param>
    /// <param name="arg"></param>
    /// <param name="isAsync"></param>
    /// <returns></returns>
    public static Task ExecuteAction<T>(Action<T> action, T arg, bool isAsync = true)
    {
        // adapt to root Action delegate and invoke 
        Action rootAction = AdaptToRootAction<T>(action, arg);
        return ExecuteAction(rootAction, isAsync);
    }


    public static Task ExecuteAction<T1, T2>(Action<T1, T2> action, T1 arg1, T2 arg2, bool isAsync = true)
    {
        // adapt to root Action delegate and invoke
        Action rootAction = AdaptToRootAction<T1, T2>(action, arg1, arg2);
        return ExecuteAction(rootAction, isAsync);
    }
}

0 个答案:

没有答案