C# 协程 WaitForSeconds产生GC(Garbage Collection)问题

本文讨论了C#协程使用WaitForSeconds可能导致的垃圾回收(GC)问题,每帧会产生额外的内存分配。推荐使用预设的等待时间来避免这个问题,并提出了一些防止GC的优化建议,如避免Invoke、使用Cached GetComponent、减少字符串操作等。

孙广东   2015.4.9   24:00

先来看看使用协程的作用一共有两点:
    1)延时(等待)一段时间执行代码;
    2)等某个操作完成之后再执行后面的代码。总结起来就是一句话:控制代码在特定的时机执行。
协程不是线程,也不是异步执行的。协程和 MonoBehaviour 的 Update函数一样也是在MainThread中执行的。使用协程你不用考虑同步和锁的问题。


对于使用协程带来GC问题,不推荐使用了!。

使用我之前封装的  游戏简单控制逻辑Clock类     可以完美解决

IEnumerator myAwesomeCoroutine()

{

    while (true)

    {

        doAwesomeStuff();

        yield return new WaitForSeconds(waitTime);

    }

} 


我想要指出的是使用 "yield return new WaitForSeconds()" 将会每帧导致垃圾分配GC,21个字节,由于"new" 部分(相对于标准的协程 "yi

### C# 协程的实现与用法 C# 中的协程可以通过 `IEnumerator` 接口和 `yield` 语句来实现[^3]。协程的核心思想是通过暂停和恢复执行,允许程序在不阻塞线程的情况下处理异步任务或迭代操作[^1]。 #### 协程的基本结构 协程通常定义为返回 `IEnumerator` 或 `IEnumerator<object>` 的方法。以下是一个简单的协程示例: ```csharp IEnumerator SimpleCoroutine() { Debug.Log("Step 1"); yield return new WaitForSeconds(2); // 暂停2秒 Debug.Log("Step 2"); yield return null; // 等待一帧 Debug.Log("Step 3"); } ``` #### 启动协程 在 Unity 中,可以使用 `StartCoroutine` 方法启动协程[^4]。例如: ```csharp void Start() { StartCoroutine(SimpleCoroutine()); } ``` #### 自定义协程管理器 如果不在 Unity 环境中,可以通过自定义协程管理器来实现类似功能[^5]。以下是一个简单的实现: ```csharp public class CoroutineManager { private IEnumerator _coroutine; public void Start(IEnumerator coroutine) { _coroutine = coroutine; } public void Update() { if (_coroutine != null && _coroutine.MoveNext()) { var current = _coroutine.Current; if (current is WaitForSeconds wait) { StartCoroutine(wait); } } else { _coroutine = null; } } private void StartCoroutine(WaitForSeconds wait) { // 模拟等待逻辑 System.Threading.Thread.Sleep((int)(wait.seconds * 1000)); } } ``` #### 常见的 `yield` 返回值类型 - `null`:等待一帧。 - `WaitForSeconds`:等待指定的时间(单位为秒)。 - `IEnumerator`:嵌套另一个协程[^3]。 #### 协程的应用场景 协程广泛用于异步任务、事件驱动编程和复杂的迭代逻辑中。例如,在游戏开发中,协程可以用来实现延迟加载资源、平滑过渡效果或定时触发事件[^4]。 ```csharp IEnumerator LoadResourcesAsync(string path) { ResourceRequest request = Resources.LoadAsync(path); yield return request; GameObject loadedObject = (GameObject)request.asset; Debug.Log("Resource loaded: " + loadedObject.name); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值