Каковы возможности CoroutineScope?

В настоящее время я изучаю сопрограммы. В onCreate моего Application класса я сделал следующее:

override fun onCreate() {
    super.onCreate()

    val job = CoroutineScope(IO).launch {
        while(true) {
            Timber.i("hello from coroutine")
            delay(1000)
        }
    }

    job.invokeOnCompletion {
        Timber.i("job.invokeOnCompletion")
    }
}

Я ожидал, что задание будет отменено после завершения onCreate, но вместо этого оно выполняется бесконечно:

2020-06-28 16:23:11.436 onCreate$job: hello from coroutine
[..]
2020-06-28 16:23:19.489 onCreate$job: hello from coroutine
2020-06-28 16:23:21.504 onCreate$job: hello from coroutine
2020-06-28 16:23:22.512 onCreate$job: hello from coroutine
2020-06-28 16:23:23.516 onCreate$job: hello from coroutine
[..]
2020-06-28 16:23:45.671 onCreate$job: hello from coroutine
  1. Так каков объем CoroutineScope? Разве его нельзя отменить, как только будет достигнут конец onCreate?
  2. Обратите внимание на результат задания: есть разрыв между 16:23: 19 .489 и 16:23: 21 .504 , отсутствует 16:23: 20. Кто-нибудь может объяснить почему?
  3. Я несколько раз принудительно выполнял сборку мусора, но результат продолжается. Можно ли ожидать, что job будет собираться мусором, поскольку это локальная переменная?

person stefan.at.wpf    schedule 28.06.2020    source источник
comment
Пока его не отменит. Вы создали свой собственный, который не отменяется вами, и поэтому он не знает о вашем намерении отменить его в onDestroy. Вместо этого вы можете использовать lifecycleScope, который сделает это за вас.   -  person EpicPandaForce    schedule 28.06.2020
comment
Разве это не должно быть сборщиком мусора, поскольку job - это локальная переменная?   -  person stefan.at.wpf    schedule 28.06.2020
comment
CoroutineScope просто группа сопрограмм? Область видимости не похожа на область видимости локальной переменной?   -  person stefan.at.wpf    schedule 28.06.2020


Ответы (1)


Нельзя собирать мусор для потока, если он все еще работает.

Сопрограмма все еще работает, и она не будет отменена после завершения onCreate (). Вы можете присоединить сопрограмму к жизненному циклу фрагмента или действия, если хотите, чтобы она автоматически отменялась при уничтожении фрагмента. Но onCreate () и функции в целом не имеют жизненного цикла. Если вы хотите добиться чего-то подобного, вам нужно иметь job.cancel() в конце вашей функции.

Итак, чтобы ответить на ваши вопросы:

  1. Нет, потоки (или сопрограммы) не отменяются произвольно.
  2. ЦП был занят другими задачами в течение 1 секунды. Например, потоки ввода-вывода не имеют такого же приоритета, как пользовательский интерфейс.
  3. Вы не можете заставить GC, вы можете только предположить, что сейчас хорошее время для сбора мусора. Вы не должны пытаться перехитрить GC. Кроме того, собирать было нечего.
person rtsketo    schedule 28.06.2020