【问题标题】:Unable to cancel coroutine started with viewModelScope无法取消使用 viewModelScope 启动的协程
【发布时间】:2020-01-04 23:42:25
【问题描述】:

我在 kotlin 的 viewModel 的 init 中启动协程。 协程在循环中侦听数据,一切正常,但正如标题所暗示的那样,我无法取消该协程(或者 viewmodel 可能没有调用清除),因为 socked 保持连接。

// viewmodel
init {
    viewModelScope.launch {
        connector()
    }
}

override fun onCleared() {
    viewModelScope.cancel()
    super.onCleared()
}

suspend fun connector() = withContext(Dispatchers.IO){
    //val socket : Socket
    try {
             // connect socket
             // listen in loop
    } catch (Exception e){//whocares}

已经尝试在活动的背压时调用finish()(也尝试了一个片段)

【问题讨论】:

  • 您的循环是否在检查协程是否被取消?取消在协程中是合作的。
  • @CommonsWare 我如何检查?尝试使用 'while (coroutineContext.isActive)' ,但无济于事,oncleared IS 被调用
  • 协程取消是合作的。您需要检查循环内的isActive,或者如果套接字阻塞线程并且协程无法到达下一个循环,则直接杀死套接字。
  • isActive 应该可以工作,假设您实际上正在检查它,而您认为自己是。如果您在 I/O 上无限期地阻塞,您将不会在这些阻塞期间进行检查。您可能会查看Korio,它似乎具有协程友好的 TCP 套接字 I/O。
  • 尝试杀死套接字,它到达了 catch 块,但是当重新启动活动时,它仍然卡在 catch 块中(协程仍然存在)。尝试在 catch 块中调用 [coroutineContext.]cancel,仍然活着,唯一能杀死它的是当我强制停止(或从 android studio 再次点击运行)时。这是我必须说的一个持久协程。

标签: android kotlin mvvm kotlin-coroutines android-viewmodel


【解决方案1】:

协程中的取消必须是合作的。即你的代码应该检查协程状态。 在您的套接字连接中,您应该检查isActiveensureActive() 至少在任何时候调用任何回调,然后再继续进行。 理想的解决方案是手动关闭套接字连接器,因为无法保证任何回调。将被调用。你也可以试试suspendCancellableCoroutine

【讨论】:

    【解决方案2】:

    这应该可以解决您的问题,将作业分配给一个变量,然后使用它来取消。

        var job : Job? = null
    
        // viewmodel
        init {
            job = viewModelScope.launch {
                connector()
            }
        }
    
        override fun onCleared() {
            job?.cancel()
            super.onCleared()
        }
    
        suspend fun connector() = withContext(Dispatchers.IO){
            //val socket : Socket
            try {
                     // connect socket
                     // listen in loop
            } ca
    

    【讨论】:

    • 协程可以通过在作用域或作业上调用 cancel() 来实现
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 2020-10-07
    • 2020-09-15
    • 2019-06-25
    • 1970-01-01
    • 2021-05-20
    • 1970-01-01
    相关资源
    最近更新 更多