Kotlin Academy · درس

الإلغاء التعاوني: ‏isActive وensureActive

اجعل coroutines قابلة للإلغاء عبر التحقق من isActive واستدعاء ensureActive.

الدرس 1 من 413 خطوة

الإلغاء التعاوني: ‏isActive وensureActive درس مجاني في Kotlin Academy على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Kotlin Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

لماذا الإلغاء التعاوني؟

تستخدم coroutines في Kotlin الإلغاء التعاوني: لا تتوقف coroutine التي أُلغيت إلا عندما تتعاون عبر فحص حالة الإلغاء. ولن تتوقف حلقة كثيفة العمليات الحسابية حتى تجري هذا الفحص.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        var i = 0
        while (true) { i++ } // never checks — never cancels!
    }
    delay(100)
    job.cancel()
    println("cancel sent but loop kept running until process ended")
}

فحص isActive

إن isActive خاصية في CoroutineScope تُرجع false بمجرد طلب الإلغاء. ويجعل فحصها داخل حلقة coroutine تتعاون مع الإلغاء.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        var i = 0
        while (isActive) {
            i++
        }
        println("Loop exited after $i iterations")
    }
    delay(10)
    job.cancel()
    job.join()
}

ensureActive()

تُطلق ensureActive() الاستثناء CancellationException إذا أُلغيت coroutine. وهي بديل مباشر للتعبير if (!isActive) throw CancellationException().

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            repeat(1_000_000) {
                ensureActive()  // throws if cancelled
                // heavy computation here
            }
        } catch (e: CancellationException) {
            println("Cancelled at iteration")
            throw e
        }
    }
    delay(5)
    job.cancel()
    job.join()
}

yield() كنقطة تعاون

تعلّق yield() تنفيذ coroutine لفترة وجيزة، مما يتيح للمجدول فحص الإلغاء وتشغيل coroutines أخرى.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        repeat(10) { i ->
            yield()  // cooperative cancellation point + gives up scheduler
            println("Step $i")
        }
    }
    delay(2)
    job.cancel()
    job.join()
    println("Done")
}

isActive مقابل ensureActive

استخدم isActive للمنطق الشرطي، مثل الخروج من حلقة بسلاسة. واستخدم ensureActive() عندما تريد تمرير الإلغاء فورًا على هيئة استثناء.

import kotlinx.coroutines.*
fun main() = runBlocking {
    launch {
        repeat(100) { i ->
            if (!isActive) {
                println("Stopping at $i, cleaning up...")
                return@launch
            }
            // work
        }
    }.also { delay(5); it.cancel(); it.join() }
}

CancellationException حالة خاصة

لا يتم تمرير CancellationException إلى الوالد — فهي تشير إلى إلغاء عادي. لا تبتلعها مطلقًا؛ أعد طرحها دائمًا أو اتركها تنتشر.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            delay(1000)
        } catch (e: CancellationException) {
            println("Caught cancellation, rethrowing")
            throw e  // important!
        }
    }
    delay(50)
    job.cancel()
    job.join()
    println("Job state: ${job.isCancelled}")
}

الإلغاء أثناء العمل المعتمد على وحدة المعالجة المركزية

بالنسبة إلى العمل المعتمد على وحدة المعالجة المركزية، أدرج ensureActive() أو yield() عند نقاط تحقق طبيعية للسماح بالإلغاء في الوقت المناسب.

import kotlinx.coroutines.*
suspend fun heavyCompute(n: Int): Long {
    var result = 0L
    for (i in 0..n) {
        ensureActive()
        result += i
    }
    return result
}
fun main() = runBlocking {
    val job = launch(Dispatchers.Default) {
        println(heavyCompute(1_000_000))
    }
    delay(10)
    job.cancel()
    job.join()
}

استخدام isActive في دالة تعليق مخصصة

يمكنك الوصول إلى isActive داخل أي دالة تعليق باستخدام coroutineContext.isActive أو currentCoroutineContext().isActive.

import kotlinx.coroutines.*
suspend fun checkable() {
    while (currentCoroutineContext().isActive) {
        delay(10)
        println("tick")
    }
}
fun main() = runBlocking {
    val job = launch { checkable() }
    delay(35)
    job.cancel()
    job.join()
}

الإلغاء مع تنظيف الموارد

حتى مع الإلغاء التعاوني، يمكن تنظيف الموارد داخل كتل finally — إذ يستمر استثناء الإلغاء في الانتشار عبرها.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try {
            repeat(100) { i ->
                ensureActive()
                delay(20)
                println("Working $i")
            }
        } finally {
            println("Cleanup done")
        }
    }
    delay(50)
    job.cancel()
    job.join()
}

الاستطلاع باستخدام isActive

تتناسب حلقات الاستطلاع تمامًا مع isActive: واصل الاستطلاع حتى يتم إلغاء coroutine.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        while (isActive) {
            println("Polling...")
            delay(100)
        }
        println("Poller stopped")
    }
    delay(350)
    job.cancel()
    job.join()
}

الفرق عن Thread.interrupted()

على عكس خيوط Java، لا تعتمد coroutines في Kotlin على علامات المقاطعة. إذ يُمثَّل الإلغاء باستخدام الاستثناءات وحالة النطاق، مما يجعله قابلًا للتركيب ومنظمًا.

import kotlinx.coroutines.*
fun main() = runBlocking {
    // Kotlin way: cooperative via isActive / ensureActive
    launch {
        ensureActive()
        println("Kotlin coroutine: cancellation is explicit and structured")
    }
}

تحقق سريع

ما الدالة التي تطرح استثناءً فور إلغاء coroutine؟

مراجعة

يتطلب الإلغاء التعاوني نقاط تحقق صريحة: isActive للخروج الشرطي، وensureActive() لطرح استثناء فورًا، وyield() للتعليق والتخلي عن الخيط. لا تبتلع CancellationException مطلقًا.

البدء مجانًا

تعلم Kotlin مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
51
الدروس
203

الأسئلة الشائعة

هل درس «الإلغاء التعاوني: ‏isActive وensureActive» مجاني؟

نعم — نص درس «الإلغاء التعاوني: ‏isActive وensureActive» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Kotlin Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Kotlin Academy 4 دروس في المجموع.

ماذا ستتعلم في «الإلغاء التعاوني: ‏isActive وensureActive»؟

اجعل coroutines قابلة للإلغاء عبر التحقق من isActive واستدعاء ensureActive. تتمرن على Kotlin Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Kotlin Academy؟

لا تُشترط خبرة سابقة. Kotlin Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.

كم من الوقت يستغرق درس «الإلغاء التعاوني: ‏isActive وensureActive»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Kotlin Academy هذا؟

نعم. كل درس في Kotlin Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. الإلغاء التعاوني: ‏isActive وensureActive
  2. ‏withTimeout وwithTimeoutOrNull
  3. التنظيف باستخدام finally وNonCancellable
  4. انتشار الإلغاء في التسلسلات الهرمية لـ Coroutine
← العودة إلى Kotlin Academy