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

Kotlin协程代码在Playground超时报错,求原因解析

Kotlin协程async代码超时报错原因分析

问题描述

我是Kotlin新手,正在学习协程及async的用法。在Kotlin Playground运行一段代码时出现错误:Evaluation stopped while it's taking too long️,但另一段包含延迟操作的代码却能正常运行,想请教报错原因。

报错代码

import kotlinx.coroutines.*
import java.util.concurrent.Executors
import kotlin.system.measureTimeMillis

val executor = Executors.newFixedThreadPool(10).asCoroutineDispatcher()

suspend fun fooAsyncS(): Int = fooAsync("").await()

fun fooAsync(id: String): Deferred<Int> = GlobalScope.async(executor) {
    delay(1000)
    1
}

fun main() = runBlocking {
    val timeElapsed = measureTimeMillis {
        fooAsyncS()
    }

    println("$timeElapsed")
    println("Hello")
}

正常运行的代码

suspend fun example(): String {
    println("computing result")
    delay(5000)
    return "data"
}

fun main() = runBlocking {
    val timeElapsed = measureTimeMillis {
        launch {
            example()
        }
    }

    println("$timeElapsed")
    println("Hello")
}

报错原因解析

两段代码的核心差异在于是否阻塞了runBlocking的主协程,结合环境限制导致问题:

  • 报错代码的问题点

    1. fooAsyncS()内部调用了await(),这个方法会阻塞当前的主协程(runBlocking创建的协程),必须等到async子协程执行完成才会继续向下执行。
    2. 你给async指定了自定义线程池executor,Kotlin Playground的受限环境对自定义线程池的协程调度支持不完善,delay(1000)挂起子协程后,线程池无法正确唤醒它,导致await()一直处于阻塞状态,触发了平台的超时限制。
    3. 另外,GlobalScope.async是不推荐的用法,它的生命周期不受控,进一步增加了在受限环境中出问题的概率。
  • 正常代码能运行的原因
    measureTimeMillis块里调用的是launch,launch只会启动子协程,不会阻塞主协程。所以measureTimeMillis瞬间执行完成,主协程直接走到println语句,整个程序的主流程很快结束,不会触发超时。至于launch里的delay(5000),因为主流程已经结束,平台不会再等待这个子协程完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 06:12:54