c# – 在没有内存分配的情况下委托Closure

c# – 在没有内存分配的情况下委托Closure,第1张

概述我写了一个Thread帮助器类,可以用来在Unity的主线程中执行一段代码. 这是蓝图的功能: public static void executeInUpdate(System.Action action) 完整的脚本非常长,会使这个帖子不必要地长.您可以看到脚本助手类here的其余部分. 然后我可以使用另一个Thread中的unity的API,如下所示: UnityThread.execute 我写了一个Thread帮助器类,可以用来在Unity的主线程中执行一段代码.

这是蓝图的功能:

public static voID executeInUpdate(System.Action action)

完整的脚本非常长,会使这个帖子不必要地长.您可以看到脚本助手类here的其余部分.

然后我可以使用另一个Thread中的unity的API,如下所示:

UnityThread.executeInUpdate(() =>{    transform.Rotate(new Vector3(0f,90f,0f));});

问题是当我使用在该委托之外声明的变量时,它会分配内存.上面的代码每帧分配104个字节.那是因为在闭包内部使用的变换变量.

现在看起来似乎什么都没有,但我这样做每秒60次,我有大约6个相机,我需要连接到屏幕上显示图像.我不喜欢生成的垃圾量.

下面是我如何从相机下载图像并将其上传到Unity的示例.我每秒约60帧. receiveVIDeoFrame()函数在单独的Thread上运行.它下载图像,将其发送到Unity的主线程,Unity将图像字节上传到Texture2D.然后,纹理2D显示为RawImage.由于UnityThread.executeInUpdate捕获闭包时发生分配.

bool doneUploading = false;byte[] vIDeoBytes = new byte[25000];public Texture2D vIDeodisplay;voID receiveVIDeoFrame(){    while (true)    {        //Download VIDeo Frame         downloadVIDeoFrameFromNetwork(vIDeoBytes);        //display VIDeo Frame         UnityThread.executeInUpdate(() =>        {            //Upload the vIDeobytes to Texture to display            vIDeodisplay.LoadImage(vIDeoBytes);            doneUploading = true;        });        //Wait until vIDeo is done uploading to Texture/displayed        while (!doneUploading)        {            Thread.Sleep(1);        }        //Done uploading Texture. Now set to false for the next run        doneUploading = false;        //Repeat again    }}

如何在不引起内存分配的情况下使用闭包?

如果那是不可能的,还有另一种方法吗?

我可以删除我用来在主线程中执行代码的类,并在主脚本中重写这些逻辑,但这将是混乱和冗长的.

解决方法 经过几个小时的实验,我发现如果你把带闭包的代码放在一个函数中,然后在Start或Awake函数中将它缓存到一个Action变量,当你在while循环中调用它时,闭包内存分配就会消失.

另外,我将doneUploading布尔变量设置为volatile,以便两个线程都可以看到更改.我不认为这个布尔变量需要lock关键字.

private volatile bool doneUploading = false;byte[] vIDeoBytes = new byte[25000];public Texture2D vIDeodisplay;Action chachedUploader;voID Start(){    chachedUploader = uploadToTexture;}voID uploadToTexture(){    UnityThread.executeInUpdate(() =>    {        //Upload the vIDeobytes to Texture to display        vIDeodisplay.LoadImage(vIDeoBytes);        doneUploading = true;    });}//running in another ThreadvoID receiveVIDeoFrame(){    while (true)    {        //Download VIDeo Frame         downloadVIDeoFrameFromNetwork(vIDeoBytes);        //display VIDeo Frame (Called on main thread)        UnityThread.executeInUpdate(chachedUploader);        //Wait until vIDeo is done uploading to Texture/displayed        while (!doneUploading)        {            Thread.Sleep(1);        }        //Done uploading Texture. Now set to false for the next run        doneUploading = false;        //Repeat again    }}

如果有人发现任何坏事,我愿意接受更多改进.虽然,我已经解决了我的问题.闭包不再分配内存.

总结

以上是内存溢出为你收集整理的c# – 在没有内存分配的情况下委托Closure全部内容,希望文章能够帮你解决c# – 在没有内存分配的情况下委托Closure所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1232793.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存