withTimeout फ़ंक्शन देता है IllegalStateException: कोई ईवेंट लूप नहीं है। एक शुरू करने के लिए रनबोलिंग {…} का उपयोग करें। Kotlin Multiplatform iOS क्लाइंट में


13

अद्यतन: यह काम करता है अगर मैं पहली बार बिना टाइमआउट के एक कोरआउट को निष्पादित करता हूं और फिर टाइमटाइमआउट करता हूं। लेकिन अगर मैं पहले एक कोरटाउन को टाइमटाइमआउट के साथ निष्पादित करता हूं तो यह मुझे एक त्रुटि देता है। वही Async के लिए भी जाता है।

मैं एक डेमो कोटलिन मल्टीप्लायटर एप्लिकेशन बना रहा हूं जहां मैं ktor के साथ API कॉल निष्पादित कर रहा हूं। मैं ktor के अनुरोध पर एक कॉन्फ़िगर करने योग्य समयबाह्य कार्य करना चाहता हूं, इसलिए मैं coroutine स्तर पर withTimeout का उपयोग कर रहा हूं।

यहाँ नेटवर्क एपीआई के साथ मेरी फ़ंक्शन कॉल है।

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.

मैं कोटलिन-कोरटाइन-देशी के 1.3.2-देशी-एमटी -1 संस्करण का उपयोग कर रहा हूं। मैंने निम्नलिखित URL पर एक नमूना डेमो एप्लिकेशन बनाया है। https://github.com/dudhatparesh/kotlin-multiplat-platform-example


त्रुटि केवल आईओएस क्लाइंट में आ रही है? Android क्लाइंट ठीक से काम करता है?
कुशाल

हां एंड्रॉइड क्लाइंट पूरी तरह से ठीक काम कर रहा है
परेश दुधात

इसी तरह के मुद्दे पर चल रहा है जब github.com/joreilly/PeopleInSpace को अपडेट करने की कोशिश कर रहा है ताकि कोरटाइंस के मूल mt संस्करण का उपयोग 1.3.3-native-mtकिया जा सके .... github.com/Kotlin/kotlinx.coroutines/issues/462 में उल्लेखित संस्करण की कोशिश कर रहा है । ऐसा लगता है कि हमें उपयोग करना चाहिए newSingleThreadContextलेकिन यह किसी कारण से हल नहीं होता है।
जॉन ओ'रिली ने

जवाबों:


5

इसलिए, जैसा कि ऊपर टिप्पणी में उल्लेख किया गया था, मेरे पास भी ऐसा ही मुद्दा था, लेकिन यह निकला कि native-mtअन्य पुस्तकालयों में सकर्मक निर्भरता के कारण यह संस्करण नहीं उठा रहा है । इसके बाद जोड़ा गया और यह अब हल हो रहा है।

        implementation('org.jetbrains.kotlinx:kotlinx-coroutines-core-native') 
        {
            version {
                strictly '1.3.3-native-mt'
            }
        }

Https://github.com/Kotlin/kotlinx.coroutines/blob/native-mt/kotlin-native-sharing.md पर भी ध्यान दें।

Https://github.com/joreilly/PeopleInSpace में इसका उपयोग करना शुरू करना


बस यही कोशिश की। एक ही त्रुटि हो रही काम नहीं किया।
परेश दुधात


जॉन के जवाब के लिए धन्यवाद, मैं नीचे दिए गए फ़ंक्शन को आईओएस से सफलतापूर्वक कॉल करने में सक्षम था `` @InternalCoroutinesApi मज़ा पृष्ठभूमि पृष्ठभूमि () {val job = GlobalScope.launch {kprint ("हम मुख्य थ्रेड्स n पर हैं") withContext (Dispatchers.Default) {kprint ("hello \ n") देरी (2000) kprint ("दुनिया \ n")}}}} `` `
Brendan Weinstein

हे जॉन। इसके लिए धन्यवाद। किसी भी विचार कैसे मैं ktor तो निर्माण करने के लिए प्राप्त कर सकते हैं? किसी भी तरह से मैं इसे उपयोग करने के लिए मजबूर कर सकता हूं 1.3.3-native-mt? मुझे मिलता हैCould not resolve org.jetbrains.kotlinx:kotlinx-coroutines-core-native:1.3.3. Required by: project :shared > io.ktor:ktor-client-ios:1.3.0 > io.ktor:ktor-client-ios-iosx64:1.3.0
कार्सन होल्जाइमर

1
@ JohnO'Reilly फिर से धन्यवाद। मैंने इसे अपने ग्रेडिंग संस्करण को 6 में अपग्रेड करके हल किया जैसे आपने उदाहरण में दिया था।
कार्सन होल्जाइमर

1

यदि आप [withTimeout]कोरटाइन में कार्यों का उपयोग करना चाहते हैं, तो आपको इंटरफ़ेस Dispatcherको लागू करने के लिए अपने संशोधित करना होगा Delay। यहाँ एक उदाहरण दिया गया है कि इसे कैसे प्राप्त किया जा सकता है:

@UseExperimental(InternalCoroutinesApi::class)
class UI : CoroutineDispatcher(), Delay {

    override fun dispatch(context: CoroutineContext, block: Runnable) {
        dispatch_async(dispatch_get_main_queue()) {
            try {
                block.run()
            } catch (err: Throwable) {
                throw err
            }
        }
    }

    @InternalCoroutinesApi
    override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation<Unit>) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeMillis * 1_000_000), dispatch_get_main_queue()) {
            try {
                with(continuation) {
                    resumeUndispatched(Unit)
                }
            } catch (err: Throwable) {
                throw err
            }
        }
    }

    @InternalCoroutinesApi
    override fun invokeOnTimeout(timeMillis: Long, block: Runnable): DisposableHandle {
        val handle = object : DisposableHandle {
             var disposed = false
                private set

            override fun dispose() {
                disposed = true
            }
        }
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeMillis * 1_000_000), dispatch_get_main_queue()) {
            try {
                if (!handle.disposed) {
                    block.run()
                }
            } catch (err: Throwable) {
                throw err
            }
        }

        return handle
    }

}

इस समाधान को आसानी से अपनी आवश्यकताओं के लिए संशोधित किया जा सकता है।

अधिक जानकारी इस थ्रेड में मिल सकती है ।


मैंने उस उपाय को भी आजमाया। फिर भी, यह वही त्रुटि दे रहा है। हालाँकि, अगर मैं किसी भी कोरआउट को निष्पादित करता हूं, जो समय समाप्त होने के साथ कोरआउट को निष्पादित करने से पहले समय समाप्त नहीं करता है तो यह ठीक काम करता है।
परेश दुधात

@PareshDudhat आपके द्वारा उल्लेखित व्यवहार अजीब है। नहीं है Dispatchers.Unconfinedडिस्पैचर, जो है तंत्र बल्कि आप क्या वर्णन कर जाते हैं। क्या आप पूरी तरह से इस बात को लेकर आश्वस्त हैं कि आप अपने कोरआउट को किस तरह लॉन्च करेंगे?
कला

मैं इसे लॉन्च (dispatchers.main) के साथ लॉन्च कर रहा हूं, मैंने इसे डिस्पैचर.main + जॉब के साथ लॉन्च करने की भी कोशिश की है लेकिन कोई मदद नहीं मिली है। मैंने गिटहब रेपो
परेश दुधात

0

कभी-कभी एंड्रॉइड ऐप के साथ आईओएस ऐप की एक अलग एसेंशियल आवश्यकता होती है। अस्थायी प्रेषण समस्या के लिए इस कोड का उपयोग करें

object MainLoopDispatcher: CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        NSRunLoop.mainRunLoop().performBlock {
            block.run()
        }
    }
}

कृपया इस मुद्दे के लिए मंच देखें: https://github.com/Kotlin/kotlinx.coroutines/issues/470


मैंने कोशिश की है कि लेकिन यह भी काम नहीं कर रहा है।
परेश दुधात
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.