更新:最初にタイムアウトなしでコルーチンを実行し、次にwithTimeoutを実行すると機能します。しかし、最初にwithTimeoutコルーチンを実行すると、エラーが発生します。同じことが非同期にも当てはまります。
私はktorを使用してAPI呼び出しを実行するデモのkotlinマルチプラットフォームアプリケーションを作成しています。コルーチンレベルでwithTimeoutを使用しているので、ktorリクエストに構成可能なタイムアウト関数を設定したいと思います。
ネットワークAPIを使用した関数呼び出しを次に示します。
suspend fun <T> onNetworkWithTimeOut(
url: String,
timeoutInMillis: Long,
block: suspend CoroutineScope.() -> Any): T {
return withTimeout(timeoutInMillis) {
withContext(dispatchers.io, block)
} as T
}
suspend fun <T> onNetworkWithoutTimeOut(url: String, block: suspend CoroutineScope.() -> Any): T {
return withContext(dispatchers.io, block) as T
}
iOSMainモジュールのAppDispatcherクラスを次に示します。
@InternalCoroutinesApi
actual class AppDispatchersImpl : AppDispatchers {
@SharedImmutable
override val main: CoroutineDispatcher =
NsQueueDispatcher(dispatch_get_main_queue())
@SharedImmutable
override val io: CoroutineDispatcher =
NsQueueDispatcher(dispatch_get_main_queue())
internal class NsQueueDispatcher(
@SharedImmutable private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
override fun dispatch(context: CoroutineContext, block: Runnable) {
NSRunLoop.mainRunLoop().performBlock {
block.run()
}
}
}
}
そのため、タイムアウト付きの関数を使用すると、iOSクライアントで次のエラーが発生します。
kotlin.IllegalStateException: There is no event loop. Use runBlocking { ... } to start one.
私はkotlin-coroutine-nativeの1.3.2-native-mt-1バージョンを使用しています。次のURLでサンプルデモアプリケーションを作成しました。 https://github.com/dudhatparesh/kotlin-multiplat-platform-example
1.3.3-native-mt
が発生します。使用newSingleThreadContext
しているようですが、何らかの理由で解決しません。