JobCancellationException Ошибка UndispatchedCoroutine в Kotlin - PullRequest
0 голосов
/ 16 июня 2020

Я все еще новичок в сопрограммах (но уже очень люблю их). У меня есть эта ошибка (и cra sh), но я не понимаю, что это значит. Что такое UndispatchedCoroutine? как он отменяется?

kotlinx.coroutines.JobCancellationException: UndispatchedCoroutine был отменен; job = "coroutine # 8": UndispatchedCoroutine {Canceled} @ fe7d397

Изменить: чтобы дать некоторый контекст, я использую Актера для выполнения обработки сообщения в сопрограмме:

@OptIn(kotlinx.coroutines.ObsoleteCoroutinesApi::class)
internal inner class HandlerFPMsg : Handler() {
    private val msgActor = coroutineScope.actor<Pair<Int, Long>>(Dispatchers.Default, capacity = Channel.UNLIMITED) {
        for(msg in channel)
            handleMessageWorker(msg.first, msg.second)
    }

    override fun handleMessage(msg: Message) {
        msgActor.offer(Pair(msg.what, msg.data.getLong("ID",-1L)))
        super.handleMessage(msg)
    }

    private suspend fun handleMessageWorker(what: Int, id: Long) {
        if (what != 0x92) Log.d("Messenger123", "Message Received: [" + what.toString(16) + "]")
        when (what) {
            MsgConstants.MSG_CONSTANT1 -> {
                someFunction()
                Log.e(TAG, "${e.message}")
            }
            MsgConstants.MSG_CONSTANT2 -> {
                if (id != lastId) return
                // -----------------------
                if (aSuspendingFunction()) {
                    msgService?.let { msgr -> aClass.sendAmsg(msgr) }
                } else {
                    // some comment 
                    someFunction()
                }
            }
        }
    }
}

если я оберну handleMessageWorker(msg.first, msg.second) блоком try catch, похоже, работает (но я не знаю, насколько правильным будет код ...)

1 Ответ

0 голосов
/ 17 июня 2020

Это не окончательный ответ, но я считаю, что комментарии слишком короткие для этого.

Судя по тому факту, что это внутренний класс, и что вы создаете свой actor с помощью coroutineScope извне, я предполагаю, что ваш coroutineScope будет завершен, что также завершит работу вашего актера. Это правильное поведение структурированного параллелизма.

Вопрос: почему область действия вашей сопрограммы прекращается.

Две основные возможности:

  1. Он привязан к жизненному циклу другого объекта. Если вы запускаете этого актера из области действия Android Activity, coroutineScope может прекратить работу после закрытия активности.
  2. Другой фрагмент кода, использующий ту же область видимости, вызывает исключение. Это также приведет к прекращению действия области действия, если только это не supervisorScope
...