当前位置: 首页 > 知识库问答 >
问题:

当您在协同程序作用域中抛出异常时,协同程序作用域是否可重用?

黎同
2023-03-14

我一直很难理解协同程序的错误处理,我已经通过以下步骤将其缩小到这个单元测试:

>

以下是测试:

fun `when you throw an exception in a coroutine scope, is the coroutine scope dead?`() {
    val parentJob = Job()
    val coroutineScope = CoroutineScope(parentJob + Dispatchers.Default)

    val deferredResult = coroutineScope.async { throw IllegalStateException() }

    runBlocking {
        try {
            deferredResult.await()
        } catch (e: IllegalStateException) {
            println("We caught the exception. Good.")
        }

        try {
            coroutineScope.async { println("we can still use the scope") }.await()
        } catch (e: IllegalStateException) {
            println("Why is this same exception still being thrown?")
        }

    }

}

下面是测试的输出:

We caught the exception. Good.
Why is this same exception still being thrown?

>

  • 为什么会这样?

    • 我的理解是,您可以正常处理异常,并通过协同程序从中恢复

    我应该如何处理例外情况?

    • 我需要创建一个新的合作项目吗
    • 如果我想继续使用同一个coroutineScope,我就不能抛出异常吗
    • 我应该返回

    注意,我使用的是Kotlin 1.3


  • 共有1个答案

    澹台华翰
    2023-03-14
    匿名用户

    当您在某个范围内启动协同路由(使用asynclaunch)时,默认情况下,协同路由失败会取消该范围,以立即取消所有其他子项。这种设计避免了悬空和丢失异常。

    这里的一般建议是:

    >

  • 除非确实需要并发,否则不要使用async/wait。当您使用挂起函数设计代码时,不需要太多地使用asyncwait

    如果您确实需要并发执行,那么请遵循以下模式:

    coroutineScope { 
        val d1 = async { doOne() }
        val d2 = async { doTwo() }
        ...
        // retrieve and process results
        process(d1.await(), d2.await(), .... )
    }
    

    如果您需要处理并发操作的失败,请在coroutineScope{...}周围放置try{...}cat{...},以捕获任何并发执行操作中的失败。

    • 还有其他高级机制(如SupervisorJob)允许细粒度异常处理。您可以在文档中阅读更多内容https://kotlinlang.org/docs/reference/coroutines/exception-handling.html

  •  类似资料:
    • 主要内容:什么是协同(coroutine)?,coroutine_test.lua 文件,实例,生产者-消费者问题,实例什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。 在任一指定时刻只有

    • 什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。 在任一指定时刻只有一个协同程序在运行,

    • 问题内容: 我想使用Java开发Web应用程序。但是我很困惑所有这些不同的技术是什么以及它们如何协同工作: HTTP 的HTML 的CSS Java脚本 jQuery的 网络容器 小程序 JSP JSTL 表达语言(EL) 在网上可以找到关于这些主题的大量资源,并且每个主题似乎都需要阅读几本书才能理解。您可以解释这些技术,以便在开始开发Web应用程序时对它们有一个基本的了解吗? 问题答案: 请注意

    • 我使用Refught2调用kotlin协同程序的API,但API的状态代码为200、400和700。当请求API和响应状态代码为400或700时,“withTimeout”协同程序可能会异常崩溃。我想处理带有“withTimeout”协同程序的状态代码400和700响应消息,或者如何自定义“协同程序”谢谢。 这是我的密码 错误消息

    • 最近,我通过学习CodeLabs教程学习了kotlin coroutine。经过一些实践,我想知道我是否可以用java编写相同的代码。首先,我在MyKotlinFragment中编写了一个简单的kotlin代码。kt文件如下: 在我的片段中调用了;它起作用了。 接下来,我打开了一个名为MyRoutineFragment的java文件。java在同一个项目中,但我无法让它工作。 我无法将第一个文件转

    • 我试图调用ViewModel中片段中的函数,但每次调用时它都会崩溃,我不知道为什么。下面是代码: 呼吁协程: 函数的代码: 如果我不使用协同程序,只使用我收到一个错误,说我必须从其他挂起函数或协同程序调用这个函数。 这就是错误: 我的ViewModel是: 在我称之为协程的片段中,我这样声明它: