我有一个关于如何将通用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);
}
}