C# Unity3D协同程序和lambda回调,安全性
调用在协同程序中声明的System.Action安全吗C# Unity3D协同程序和lambda回调,安全性,c#,unity3d,lambda,C#,Unity3d,Lambda,调用在协同程序中声明的System.Action安全吗 IEnumerator MyCoroutine(){ bool myBool = true; System.Action action = ()=>{myBool=false;} StartCoroutine (MyOtherCoroutine(action));//just launch and forget about it } IEnumerator MyOtherCoroutine(Sys
IEnumerator MyCoroutine(){
bool myBool = true;
System.Action action = ()=>{myBool=false;}
StartCoroutine (MyOtherCoroutine(action));//just launch and forget about it
}
IEnumerator MyOtherCoroutine(System.Action dangerous_callback){
yield return null;
yield return null;//skip several frames
yield return null;
dangerous_callback.Invoke();//will cause problems? The owner coroutine (and it's myBool) is no longer on stack
}
我关心的是在第一个协同程序中分配的myBool
<代码>myothercorroutine不会等到myothercorroutine
完成。我可以看到这个系统。操作不会被收集,因为它确实仍然被myothercorroutine
引用,但是myocroutine
(操作修改的布尔变量)应该已经被释放了
但这似乎是一个可能的内存泄漏,这可能是不可能的
以后再抓?只是问问用它是否合适
没有内存泄漏。这样做完全没问题,如果您需要在一个协程函数中进行回调,也可以这样做。请记住,这是C语言,在C语言中创建内存泄漏比使用C++更困难,除非你滥用Unity的API,这些API可能在本地(C++)方面造成内存泄漏,但这里不是这样。
尽管如此,在调用操作之前,您应该先检查操作是否为null
,否则可能会出现代码中的一些问题
if (dangerous_callback != null)
dangerous_callback.Invoke();
您是否遇到了问题,或者您是否询问这样做是否合适?我认为在协同路由中使用回调比较方便,因为不可能使用“ref”或“out”参数。但这似乎是一个可能的内存泄漏,以后可能无法捕获?只是问问用它是否合适,谢谢!这真的很奇怪,因为myBool直接属于MyCoroutine,所以我假设操作会尝试访问一些已取消分配的内存。我一直认为它们是一旦到达}就会从执行堆栈中删除的函数。因此,在c#中,在调用回调之前,将保留此原始协同程序?操作
是一个委托
,它是一个。当您将它传递给另一个协程函数时,GC将允许它一直存在,直到该协程函数存在为止。如果在任何地方都有它的引用,它将永远不会被释放。当执行myothercorroutine
时,不存在对它的引用,因此现在可以由GC收集它。很抱歉这么固执:D但是在第一个corroutine中分配的myBool呢<代码>myothercorroutine
不会等到myothercorroutine
完成。我可以看到该系统。操作不会被收集,因为它确实仍然被myothercorroutine
引用,但是myocroutine
(操作修改其布尔变量)应该已经被释放?没问题。来自C++的C语言使用时会遇到很多问题。“MyCustomer(操作修改其布尔变量)应该已被释放?”否。由于它在Action
引用类型或Action
变量中被引用,编译器将myBool
变量移动到助手类中。见下文。因为您使用了lambda,所以它会创建一个闭包。我想补充一点,您可以使用null传播运算符在一行中编写它:hazardous_callback?.Invoke()代码>