C#协程停止重启后重复执行问题的修复咨询
问题分析与解决方案
你代码里的几个致命问题
- 重复定义同名方法:写了两个
IEnumerator _Coroutine(),C#不允许同名同参数的方法重复定义,这连编译都过不了。 - 停止协程的方式完全错误:
StopCoroutine(_Coroutine())是拿新生成的枚举器去停止,根本匹配不到正在运行的协程实例,等于白调用。 - OnClick里的启动代码写错了:
StartCoroutine(StartCoroutine())是嵌套调用启动协程的方法,完全不符合逻辑,应该启动延迟重启的协程。 - 协程递归调用导致无法追踪:原来的协程里自己调用自己启动新协程,每次点击都会新增独立的协程链,根本停不干净。
修正后的代码
public float Numbers; public float Gold; // 存储正在运行的工作协程实例,方便精准停止 private Coroutine _runningWorkCoroutine; public void BuyPerson() { if (Gold >= 10) { Gold -= 10; // 启动前先停止已有的协程,避免重复启动 StopWorkCoroutine(); _runningWorkCoroutine = StartCoroutine(WorkCoroutine()); } } // 业务逻辑协程:每3秒执行一次Numbers累加 private IEnumerator WorkCoroutine() { while (true) // 用while循环代替递归调用,更易控制 { Numbers++; // 原来的Numbers = Numbers++;是无效的,直接写Numbers++就行 yield return new WaitForSeconds(3); } } public void OnClick() { // 先停止当前运行的工作协程 StopWorkCoroutine(); // 启动延迟1秒的协程,之后重启工作协程 StartCoroutine(RestartDelayCoroutine()); } // 延迟重启的协程:等待1秒后重启工作协程 private IEnumerator RestartDelayCoroutine() { yield return new WaitForSeconds(1); _runningWorkCoroutine = StartCoroutine(WorkCoroutine()); } // 封装停止协程的方法,避免重复代码 private void StopWorkCoroutine() { if (_runningWorkCoroutine != null) { StopCoroutine(_runningWorkCoroutine); _runningWorkCoroutine = null; } }
关键修正点说明
- 用
Coroutine变量存储协程实例:每次启动工作协程时,把返回的Coroutine对象存起来,停止时直接用这个实例,就能精准停止正在运行的协程,不会出现停不掉的情况。 - 用
while(true)代替递归调用:原来的协程递归调用自己会生成多个独立协程链,用循环的话,整个逻辑在一个协程实例里,停止起来更干净。 - 修正无效的累加代码:
Numbers = Numbers++;是错误的,后置自增运算符会先返回原值再自增,赋值后等于没变化,直接写Numbers++即可。 - 封装停止逻辑:把停止协程的代码抽成方法,避免重复写判断逻辑,代码更整洁。
- 拆分协程职责:把业务逻辑和延迟重启的逻辑分成两个独立协程,职责更清晰,也避免了同名方法的问题。
内容的提问来源于stack exchange,提问作者Iluha209
相关产品推荐
相关产品推荐

