如何使协程从外部调用按顺序运行

时间:2019-04-01 13:44:56

标签: kotlin kotlin-coroutines

我是协程的真正新手,它是如何工作的,我已经读了很多有关它的书,但是我似乎不明白如何或是否可以实现自己的最终目标。

我将尽我所能详细解释。无论如何,这是我的目标:

Ensure that coroutines run sequentially when a method that has said coroutine is called.

我创建了一个与我想要发生的情况相匹配的测试:

class TestCoroutines {

  @Test
  fun test() {
    println("Starting...")

    runSequentially("A")
    runSequentially("B")

    Thread.sleep(1000)
  }

  fun runSequentially(testCase: String) {
    GlobalScope.launch {
      println("Running test $testCase")
      println("Test $testCase ended")
    }
  }
}

重要提示::我无法控制某人将调用runSequentially函数的次数。但我想保证会按顺序调用它。

此测试运行以下输出:

Starting...
Running test B
Running test A
Test A ended
Test B ended

Starting...
Running test A
Running test B
Test B ended
Test A ended

This is the output I want to achieve :
Starting...     
Running test A
Test A ended
Running test B
Test B ended

我想我理解为什么会这样:每次我打电话给runSequentially时,我都会创建一个新的Job,该Job正在运行,并且异步运行。

协程是否有可能保证它们仅在之前(如果正在运行)完成后才能运行,而我们无法控制所说的协程被调用多少次?

1 个答案:

答案 0 :(得分:3)

您要查找的是将请求排序的队列和为请求服务的工作程序的组合。简而言之,您需要一个 actor :

private val testCaseChannel = GlobalScope.actor<String>(
        capacity = Channel.UNLIMITED
) {
    for (testCase in channel) {
        println("Running test $testCase")
        println("Test $testCase ended")
    }
}

fun runSequentially(testCase: String) = testCaseChannel.sendBlocking(testCase)