Kotlin: вернуть карту асинхронности (start = CoroutineStart.LAZY) - PullRequest
0 голосов
/ 28 ноября 2018

Я хотел бы вернуть карту запущенных сопрограмм и использовать их (запуск / отмена) в другой функции.

Проблема в том, что функция getMap () в следующих зависаниях.Почему это так и можно ли вернуть такую ​​карту из функции?

import kotlinx.coroutines.*

suspend fun getMap(): LinkedHashMap<String, Deferred<Any>> {
    return withContext(Dispatchers.Default) {
        val map = linkedMapOf<String, Deferred<Any>>()
        map["1"] = async(start = CoroutineStart.LAZY) { 1 }
        map["2"] = async(start = CoroutineStart.LAZY) { 2 }
        map;
    }
}

fun main() {
    runBlocking {
        val map = getMap()
        println("not happening")
    }
}

1 Ответ

0 голосов
/ 28 ноября 2018

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

fun main() {
    runBlocking {
        withContext(Dispatchers.Default) {
            launch(start = CoroutineStart.LAZY) { 1 }
        }
        println("not happening")
    }
}

Это также не завершено.Причина в том, что вы использовали withContext ненадлежащим образом.У вашего getMap() нет причин быть suspend fun.

Вместо withContext вам нужно установить область сопрограммы для этих вызовов async.Например, это будет работать:

fun getMap(): Map<String, Deferred<Any>> =
        linkedMapOf<String, Deferred<Any>>().also { map ->
            with(GlobalScope) {
                map["1"] = async(start = CoroutineStart.LAZY) { 1 }
                map["2"] = async(start = CoroutineStart.LAZY) { 2 }
            }
        }

fun main() {
    val map = getMap()
    println("now it's happening")
}

Здесь вы используете глобальную область сопрограмм, поэтому вы не получаете автоматического отмены.Если вы хотите решить эту проблему, замените ее чем-нибудь другим.

...