You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }
}

关键修正点说明

  1. 用Coroutine变量存储协程实例:每次启动工作协程时,把返回的Coroutine对象存起来,停止时直接用这个实例,就能精准停止正在运行的协程,不会出现停不掉的情况。
  2. 用while(true)代替递归调用:原来的协程递归调用自己会生成多个独立协程链,用循环的话,整个逻辑在一个协程实例里,停止起来更干净。
  3. 修正无效的累加代码:Numbers = Numbers++;是错误的,后置自增运算符会先返回原值再自增,赋值后等于没变化,直接写Numbers++即可。
  4. 封装停止逻辑:把停止协程的代码抽成方法,避免重复写判断逻辑,代码更整洁。
  5. 拆分协程职责:把业务逻辑和延迟重启的逻辑分成两个独立协程,职责更清晰,也避免了同名方法的问题。

内容的提问来源于stack exchange,提问作者Iluha209

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:04:57