Непредсказуемый порядок выполнения сопрограмм? - PullRequest
0 голосов
/ 29 ноября 2018

Это то, что я подумал: при использовании сопрограмм вы накапливаете асинхронные операции, и как только вы закончите с синхронными операциями .. вызывайте их в порядке FIFO ... но это не всегда верно

В этом примере выполучите то, что я ожидал:

fun main() = runBlocking {
   launch {
      println("1")
   }

   launch {
      println("2")
   }

   println("0")
}

Также здесь (с вложенным запуском):

fun main() = runBlocking {
   launch {
      println("1")
   }

   launch {
      launch {
         println("3")
      }

      println("2")
   }

   println("0")
}

Теперь в этом примере с построителем области видимости и созданием другой «стопки» (не реальный термин) порядок меняется, но все же .. вы получите, как и ожидалось

fun main() = runBlocking {
   launch {
      println("2")
   }

   // replacing launch
   coroutineScope {
      println("0")
   }

   println("1")
}

Наконец ... причина этого вопроса .. Пример 2 с построителем области действия:

fun main() = runBlocking {
   launch {
      println("3")
   }

   coroutineScope {
      launch {
         println("1")
      }

      println("0")
   }

   println("2")
}

Я получаю это:0 3 1 2

Почему ??

Было ли мое предположение неверным, и это не так, как работают сопрограммы

Если это так ... то как мне определить правильный порядок при кодировании

отредактировано: я пробовал запускать один и тот же код на разных машинах и на разных платформах, но всегда получал один и тот же результат ... также пробовал более сложное вложение, чтобы доказать неизменность результатов

И копатьДокументация обнаружила, что сопрограммы простопреобразование кода (как я изначально думал)

Помните, что даже если им нравится называть их «легковесными» потоками, они работают в единственном «реальном» потоке (примечание: без newSingleThreadContext)

Таким образом, я решил, что порядок выполнения предварительно установлен во время компиляции и не определен во время выполнения

В конце концов .. Я все еще не могу предвидеть порядок ... и это то, что я хочу

1 Ответ

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

Не предполагайте, что сопрограммы будут выполняться в определенном порядке, среда выполнения решит, что лучше всего запускать, когда и в каком порядке.В этом вам может быть заинтересована документация kotlinx.coroutines .Он отлично объясняет, как они работают, а также предоставляет несколько удобных абстракций, помогающих управлять сопрограммами более разумно.Я лично рекомендую проверить каналов , заданий и Отложенных (асинхронных / ожидающих) .

Например, если я хотел, чтобы все было сделано вопределенный порядок по номеру, я бы использовал каналы, чтобы убедиться, что все поступило в нужном мне порядке.

runBlocking {
    val channel = Channel<Int>()
    launch {
        for (x in 0..5) channel.send(x * x)
        channel.close()
    }

    for (msg in channel) {
        // Pretend we're doing some work with channel results
        println("Message: $msg")
    }
}

Надеюсь, это даст вам больше контекста или что такое сопрограммы и для чего они хороши.

...