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

异步函数串行执行异常排查:isExecuting无法重置为false

问题:异步函数串行执行时锁变量无法重置为false

我希望串行执行异步函数,即等待前一个函数执行完毕后再启动下一个。为此,我创建了布尔变量isExecuting作为锁,用于阻塞直到可以执行下一个函数。但发现isExecuting被设为true后再也无法被设为false,请问原因是什么?

测试代码

test('Should execute serially', () async {
  WidgetsFlutterBinding.ensureInitialized();
  final example = DoSynchronously();
  example.convertToSync();
});

示例代码

class DoSynchronously {  

  static bool isExecuting = false;
  static const readDelay = 1000;

  void convertToSync() {
    while (true) {
      waitToExecute();
      isExecuting = true;
      anAsyncFunction();
    }
  }

  void waitToExecute() {
    while (isExecuting) {
      print("read delay");
      sleep(
        const Duration(milliseconds: readDelay),
      );
    }
  }

  Future<void> anAsyncFunction() async {
    startExecuting();
    await Future.delayed(Duration(seconds: 1), () => 'Delayed 2 seconds.')
        .then((result) => print(result));
    stopExecuting();
  }

  void startExecuting() {
    isExecuting = true;
    print("executing = true");
  }

  void stopExecuting() {
    isExecuting = false;
    print("Stopped executing");
  }
}

问题原因

核心问题是同步阻塞代码彻底卡住了事件循环,导致异步函数的后续逻辑根本没机会执行:

  • convertToSync是同步的无限循环,调用waitToExecute时,里面的sleep是同步阻塞方法,会直接霸占当前线程,完全阻断事件循环。
  • 调用anAsyncFunction()时,因为convertToSync没使用await等待它完成,函数刚执行到await就被挂起,主线程立刻回到循环里,再次调用waitToExecute。
  • 此时isExecuting已经被设为true,waitToExecute里的while+sleep会一直锁死主线程,事件循环无法处理Future.delayed完成后的回调,自然跑不到stopExecuting()来重置锁状态。

简单说:同步阻塞的代码把线程占死了,异步任务的收尾逻辑根本没机会运行。


正确的串行执行实现

要实现异步函数串行执行,得用异步循环+await等待任务完成,不能用同步阻塞的方式:

class DoSynchronously {  

  static bool isExecuting = false;
  static const readDelay = 1000;

  // 改为异步函数
  Future<void> convertToSync() async {
    while (true) {
      // 用异步等待替代同步阻塞,不卡事件循环
      while (isExecuting) {
        print("read delay");
        await Future.delayed(const Duration(milliseconds: readDelay));
      }
      await anAsyncFunction(); // 等待上一个异步任务完全结束
    }
  }

  Future<void> anAsyncFunction() async {
    isExecuting = true;
    print("executing = true");
    await Future.delayed(Duration(seconds: 1), () => 'Delayed 2 seconds.')
        .then((result) => print(result));
    isExecuting = false;
    print("Stopped executing");
  }
}

关键修改点:

  • 把convertToSync改成异步函数,用await等待每个anAsyncFunction执行完成,确保串行逻辑。
  • 替换同步sleep为异步Future.delayed,让事件循环能正常处理其他异步回调。
  • 去掉冗余的startExecuting/stopExecuting方法,直接在异步函数内维护锁状态,减少不必要的层级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 06:15:17