如何调用不同参数的方法作为Action?

How to call methods with different parameters as Action?

我正在使用 Unity 开发游戏,而 Unity 不是线程安全的,所以每当我在不同的线程上进行一些计算并想返回 Unity 时,我需要在某种队列中对调用进行排队,以便 Unity 可以接受这些任务并在 Unity 线程上执行它们。这是我使用工具完成工作的代码:

public class Test : MonoBehaviour
{
    Thread someThread;

    private void Awake() //Executes on application start
    {
        someThread = new Thread(SomeThreadMethod);
        someThread.Start();
    }

    void SomeThreadMethod()
    {
        ExecuteInUpdate(MethodCalledNotInUnityThread);
    }

    // methods that I call from not unity thread but want to execute it IN unity thread
    void MethodCalledNotInUnityThread()
    {
        Debug.Log("Hello from UnityThread");
    }

    //--------------------------------------------------------------------------------
    //Tool for executing things in Unity Thread

    List<Action> actionQueues = new List<Action>();
    List<Action> actionCopiedQueue = new List<Action>();

    private volatile static bool noActionQueue = true;

    public void ExecuteInUpdate(Action _action)
    {
        lock (actionQueues)
        {
            actionQueues.Add(action);
            noActionQueue = false;
        }
    }

    public void Update()//runs all time, sort of while(true) loop in unity thread
    {
        if (noActionQueue)
        {
            return;
        }

        actionCopiedQueue.Clear();

        lock (actionQueues)
        {
            actionCopiedQueue.AddRange(actionQueues);
            actionQueues.Clear();
            noActionQueue = true;
        }

        for (int i = 0; i < actionCopiedQueue.Count; i++)
        {
            actionCopiedQueue[i]();
        }
    }
}

但问题是它只适用于不带参数的方法。如果我做了这样的方法:

    void MethodCalledNotInUnityThread1(int _arg)
    {
        Debug.Log("Hello from UnityThread" + _arg);
    }

我无法调用它,因为它有参数。我尝试使用带有通用参数的 Action

    Action<int> action

但是我只能传递只接受一个参数的方法,它是 int。我有很多方法采用不同数量的 diffenet 参数,我该怎么做?

我想实现这样的目标:

    Dictionary<Action, object[]> paramsForAction = new Dictionary<Action, object[]>();

    public void ExecuteInUpdate(Action _action, params object[] _args)
    {
        paramsForAction.Add(action, args);//save params for action

        //add action to queue
    }

    public void Update()
    {
        //find action to execute

        object[] args = paramsForAction[actionToExecute];//get params for action
        actionToExecute(args);

    }

当然它不起作用,也没有任何意义,但希望你能得到我想要做的事情。

只需将方法调用包装在 lambda 表达式中即可:

Action act = () => MethodCalledNotInUnityThread1(argVal1, argVal2); ExecuteInUpdate(act);

您也可以只使用 Action<T>,其中 T 是该方法的第一个参数。然后还有 Action<T1, T2> 两个参数等

如果你想要 return 类型,Func<TResult> 是完全相同的想法,但具有 return 类型的类型。 Func<TResult, TParam1>,等等