Kotlin协程与超时

我正在写一个测试函数,它应该运行一个块或(当达到一定的超时时间)引发exception。

我在Kotlin的Coroutines试了Coroutines ,但是结束了CoroutinesCompletableFuture的混合:

 fun  runBlockWithTimeout(maxTimeout: Long, block: () -> T ): T { val future = CompletableFuture() // runs the coroutine launch { block() } return future.get(maxTimeout, TimeUnit.MILLISECONDS) } 

这有效,但我不确定这是否是解决kotlin问题的有效方法。

我也尝试了其他方法:

 runBlocking { withTimeout(maxTimeout) { block() } } 

但这似乎不工作,只要block调用例如Thread.sleep(...)

那么CompletableFuture方法是否还有更好的方法呢?

更新1我想实现的是:

异步集成 – 测试代码(比如从RabbitMq接收数据)应该像这样测试:

 var rabbitResults: List = ... // are filled async via RabbitListeners ... waitMax(1000).toSucceed { assertThat(rabbitResults).hasSize(1) } waitMax(1000).toSucceed { assertThat(nextQueue).hasSize(3) } ... 

withTimeout { ... }被设计为取消正在进行的超时操作,这只有在有问题的操作是可以取消的情况下才有可能。

future.get(timeout, unit)的原因是它只等待超时。 它实际上并没有以任何方式取消或中止后台操作,在超时过后仍然继续执行。

如果你想用协程来模仿类似的行为,那么你应该等待超时,像这样:

 val d = async { block() } // run the block code in background withTimeout(timeout, unit) { d.await() } // wait with timeout 

它工作正常,因为await是一个可以取消的函数,你可以通过阅读它的API文档来validation。

但是,如果您想要在超时时间内取消正在进行的操作,则应该以异步和可取消的方式实现您的代码。 取消是合作的 ,因此,要开始,您在代码中使用的底层库必须提供支持取消正在进行的操作的异步API。

您可以在协程指南的相应章节中阅读关于取消和超时的更多信息,并观看KotlinConf关于协同工作的深入了解如何将协同工作与异步库集成。