Kotlin 协程延迟不适用于 IOS 队列调度程序
Kotlin coroutines delay do not work on IOS queue dispatcher
我有一个 KMM 应用程序,并且有代码:
fun getWeather(callback: (WeatherInfo) -> Unit) {
println("Start loading")
GlobalScope.launch(ApplicationDispatcher) {
while (true) {
val response = httpClient.get<String>(API_URL) {
url.parameters.apply {
set("q", "Moscow")
set("units", "metric")
set("appid", weatherApiKey())
}
println(url.build())
}
val result = Json {
ignoreUnknownKeys = true
}.decodeFromString<WeatherApiResponse>(response).main
callback(result)
// because ApplicationDispatcher on IOS do not support delay
withContext(Dispatchers.Default) { delay(DELAY_TIME) }
}
}
}
并且如果我将 withContext(Dispatchers.Default) { delay(DELAY_TIME) }
替换为 delay(DELAY_TIME)
执行将永远不会返回到 while 循环并且它只会有一次迭代。
IOS 的 ApplicationDispatcher
看起来像:
internal actual val ApplicationDispatcher: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
internal class NsQueueDispatcher(
private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatchQueue) {
block.run()
}
}
}
从 delay
源代码我可以猜到,应该返回 DefaultDelay
并且应该有类似的行为 with/without withContext(Dispatchers.Default)
/** Returns [Delay] implementation of the given context */
internal val CoroutineContext.delay: Delay get() = get(ContinuationInterceptor) as? Delay ?: DefaultDelay
谢谢!
P.S。我从 ktor-samples.
得到了 ApplicationDispatcher
可能ApplicationDispatcher
是一些旧东西,你不需要再使用它了:
CoroutineScope(Dispatchers.Default).launch {
}
或
MainScope().launch {
}
并且不要忘记使用 -native-mt
版本的协程,更多信息请参见 issue
我有一个 KMM 应用程序,并且有代码:
fun getWeather(callback: (WeatherInfo) -> Unit) {
println("Start loading")
GlobalScope.launch(ApplicationDispatcher) {
while (true) {
val response = httpClient.get<String>(API_URL) {
url.parameters.apply {
set("q", "Moscow")
set("units", "metric")
set("appid", weatherApiKey())
}
println(url.build())
}
val result = Json {
ignoreUnknownKeys = true
}.decodeFromString<WeatherApiResponse>(response).main
callback(result)
// because ApplicationDispatcher on IOS do not support delay
withContext(Dispatchers.Default) { delay(DELAY_TIME) }
}
}
}
并且如果我将 withContext(Dispatchers.Default) { delay(DELAY_TIME) }
替换为 delay(DELAY_TIME)
执行将永远不会返回到 while 循环并且它只会有一次迭代。
IOS 的 ApplicationDispatcher
看起来像:
internal actual val ApplicationDispatcher: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())
internal class NsQueueDispatcher(
private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
dispatch_async(dispatchQueue) {
block.run()
}
}
}
从 delay
源代码我可以猜到,应该返回 DefaultDelay
并且应该有类似的行为 with/without withContext(Dispatchers.Default)
/** Returns [Delay] implementation of the given context */
internal val CoroutineContext.delay: Delay get() = get(ContinuationInterceptor) as? Delay ?: DefaultDelay
谢谢!
P.S。我从 ktor-samples.
得到了ApplicationDispatcher
可能ApplicationDispatcher
是一些旧东西,你不需要再使用它了:
CoroutineScope(Dispatchers.Default).launch {
}
或
MainScope().launch {
}
并且不要忘记使用 -native-mt
版本的协程,更多信息请参见 issue