如何调用不同参数的方法作为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>
,等等
我正在使用 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>
,等等