উইথটাইমআউট ফাংশন ইলিজালস্টেট এক্সপশন দেয়: কোনও ইভেন্ট লুপ নেই। একটি শুরু করতে রানব্লকিং {…} ব্যবহার করুন। কোটলিন মাল্টিপ্লাটফর্ম আইওএস ক্লায়েন্টে


13

আপডেট: আমি প্রথম টাইমআউট ছাড়াই এবং তারপরে টাইমআউট দিয়ে যদি কোনও কর্টিন কার্যকর করি তবে এটি কাজ করে। তবে আমি যদি প্রথমে টাইমআউট দিয়ে কোনও কর্টিন কার্যকর করি তবে এটি আমাকে একটি ত্রুটি দেয়। একই হিসাবে Async জন্য যায়।

আমি একটি ডেমো কোটলিন মাল্টিপ্লাটফর্ম অ্যাপ্লিকেশন তৈরি করছি যেখানে আমি কোটারের সাথে একটি এপিআই কল চালাচ্ছি। আমি ktor অনুরোধে একটি কনফিগারযোগ্য টাইমআউট ফাংশন করতে চাই তাই আমি কর্টাইন স্তরে টাইমআউট সহ ব্যবহার করছি।

নেটওয়ার্ক এপিআই সহ আমার ফাংশন কল এখানে।

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
}

আইওএসমাইন মডিউলটির জন্য এখানে আমার অ্যাপডিস্প্যাচার ক্লাস।

@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()
        }
    }
}

}

সুতরাং সময়সীমা সহ ফাংশনটি আমাকে আইওএস ক্লায়েন্টে নিম্নলিখিত ত্রুটি দেয়।

kotlin.IllegalStateException: There is no event loop. Use runBlocking { ... } to start one.

আমি কোটলিন-কর্টিন-নেটিভের ১.৩.২-স্থানীয়-এমটি -১ সংস্করণ ব্যবহার করছি। আমি নিম্নলিখিত URL এ একটি নমুনা ডেমো অ্যাপ্লিকেশন তৈরি করেছি। https://github.com/dudhatparesh/kotlin-multiplat-platform-example


ত্রুটিটি কি কেবল আইওএস ক্লায়েন্টে আসবে? অ্যান্ড্রয়েড ক্লায়েন্ট সঠিকভাবে কাজ করে?
কুশল

হ্যাঁ অ্যান্ড্রয়েড ক্লায়েন্ট পুরোপুরি
ঠিকঠাক

আমি যখন কারথাইনগুলির স্থানীয় এমটি সংস্করণ ব্যবহার করার জন্য github.com/joreilly/PeopleInSpace আপডেট করার চেষ্টা করছি তখন অনুরূপ ইস্যুতে দৌড়াচ্ছি .... github.com/Kotlin/kotlinx.coroutines/issues/462 এ1.3.3-native-mt উল্লিখিত সংস্করণ চেষ্টা করছি । মনে হচ্ছে আমাদের ব্যবহার করা উচিত 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 এ এটি ব্যবহার শুরু করা


সবেমাত্র চেষ্টা করেছি। একই ত্রুটি পেয়ে কাজ হয়নি।
পরেশ দুধহাট

সংগ্রহস্থলটিতে আপনার সংশোধনটি
পরেশ দুধহাট

জন এর জবাবের জন্য ধন্যবাদ আমি আইওএস `` `@ ইনটার্নাল কোর্টাইনস এপি মজাদার ব্যাকগ্রাউন্ড টেস্ট () {ভল জব = গ্লোবালস্কোপ.লাঞ্চ {কেপ্রিন্ট (" আমরা মূল থ্রেডে \ n ") কনটেক্সট (ডিসপ্যাচারস.ডাফল্ট) এর সাথে সফলভাবে নীচের ফাংশনটি কল করতে সক্ষম হয়েছি pr কেপ্রিন্ট ("হ্যালো \ n") বিলম্ব (2000) কেপ্রিন্ট ("ওয়ার্ল্ড \ n")}}} `` `
ব্রেন্ডন ওয়েইনস্টেইন

আরে জন এর জন্য ধন্যবাদ. আমি কীভাবে তৈরি করতে পারি তার পরে কোনও ধারণা? যেভাবেই আমি এটি ব্যবহার করতে বাধ্য করতে পারি 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
@ জন ও'রিলি আবার ধন্যবাদ। উদাহরণস্বরূপ আপনার গ্রেডেল সংস্করণটিকে 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
    }

}

আপনার সমাধানের জন্য এই সমাধানটি সহজেই সংশোধন করা যেতে পারে।

আরও তথ্য এই থ্রেডে পাওয়া যাবে ।


আমি সেই সমাধানটিও চেষ্টা করেছিলাম। তবুও, এটি একই ত্রুটি দিচ্ছে। যাইহোক, যদি আমি টাইমআউট সহ করাউটিন নির্বাহের আগে টাইমআউট না থাকা এমন কোনও কাউউটিন কার্যকর করি তবে এটি ঠিক কাজ করে।
পরেশ দুধহাট

@ পরেশদুহাত আপনি যে আচরণটি উল্লেখ করেছেন তা বরং আজব। সেখানে Dispatchers.Unconfinedপ্রেরণকারী রয়েছে, যার বর্ণনা দেওয়ার মতোই মেকানিজম রয়েছে। আপনি নিজের কর্টিন চালু করার উপায় সম্পর্কে কি সম্পূর্ণ নিশ্চিত?
শিল্প

আমি এটিকে লঞ্চ (dispatchers.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


আমি চেষ্টা করেছি কিন্তু এটি কাজ করছে না।
পরেশ দুধহাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.