Kotlin 取消异常何时发生?

Kotlin 取消异常何时发生?,kotlin,kotlin-coroutines,coroutine,Kotlin,Kotlin Coroutines,Coroutine,我一直在读关于用协同程序处理异常的书,但是有一些事情我还不清楚 何时发生CancellationException?我是否必须将协同路由分配给一个作业,然后调用job.cancel()才能执行它 看看我的代码,它会被捕获吗?还是说第一次拦截没用 fun调用(params:params,onResult:(UseCaseResponse)?){ 协同路由示波器(Dispatchers.Main)。启动{ 试一试{ val结果=运行(参数) onResult?.onSuccess(结果) Log

我一直在读关于用协同程序处理异常的书,但是有一些事情我还不清楚

  • 何时发生CancellationException?我是否必须将协同路由分配给一个作业,然后调用job.cancel()才能执行它

  • 看看我的代码,它会被捕获吗?还是说第一次拦截没用

  • fun调用(params:params,onResult:(UseCaseResponse)?){
    协同路由示波器(Dispatchers.Main)。启动{
    试一试{
    val结果=运行(参数)
    onResult?.onSuccess(结果)
    Log.d(标记“响应:$result”)
    }捕获(e:取消异常){
    Log.d(标记“Error:$e”)
    onResult?.onError(apiErrorHandler.traceErrorException(e))
    }捕获(e:例外){
    Log.d(标记“Error:$e cause:${e.cause}”)
    onResult?.onError(apiErrorHandler.traceErrorException(e))
    }
    }
    }
    
    这听起来可能是一个愚蠢的答案,但当有人抛出它时,就会出现
    取消异常

    基本上,是的,当取消协同程序(或其父协同程序)时(是的,通过
    job.cancel()
    )应该引发此异常。但是工程师有责任编写suspend函数来检查它是否被取消,并采取尊重的行动(例如,抛出
    CancellationException
    ,就像
    kotlinx.coroutines
    中的所有暂停函数一样)。因此,您的代码是否捕获了
    CancellationException
    取决于
    run(params)
    内部发生的情况


    有关更多信息和代码示例,请参阅和。

    OK,因此在运行内部我调用我的存储库:
    覆盖挂起有趣的运行(params:params):BuffDomainModel{return repository.getBuff(params.id)}
    它将使用改型
    类BuffRepository{suspend fun getBuff(buffId:Long)进行rest api调用=BuffApi.inversionservice.getBuff(buffId.result.toDomainModel()}
    接口BuffApiService{@GET(“buffs/{buffId}”)挂起fun getBuff(@Path(“buffId”)buffId:Long):BuffResponse}
    所以回答我自己的问题,不,它不会被捕获,因为我没有抛出它。我说的对吗?看来你是对的。还有一个关键原语,
    suspendcancelablecoroutine
    ,当你取消coroutine时,它以一个
    CancellationException
    完成。因此,实际上您很少需要显式地检查
    isActive
    标志,但必须注意不要使用
    suspendCoroutine
    ,因为这是不可取消的。
        fun invoke(params: Params, onResult: (UseCaseResponse<Type>)?) {
            CoroutineScope(Dispatchers.Main).launch {
                try {
                    val result = run(params)
                    onResult?.onSuccess(result)
                    Log.d(TAG, "Response: $result")
                } catch (e: CancellationException) {
                    Log.d(TAG, "Error: $e")
                    onResult?.onError(apiErrorHandler.traceErrorException(e))
                } catch (e: Exception) {
                    Log.d(TAG, "Error: $e cause: ${e.cause}")
                    onResult?.onError(apiErrorHandler.traceErrorException(e))
                }
            }
        }