suspend function: یہ کیا ہے، نحو اور coroutines میں کام

مصنف: IT Sectr اشاعت: 2026-06-22 مطالعے کا وقت: 9 منٹ

Suspend function ایک ایسا فنکشن ہے جس میں suspend موڈیفائر ہوتا ہے جو تھریڈ کو بلاک کیے بغیر اپنی عملدرآمد روک سکتا ہے اور بعد میں اسی coroutine میں دوبارہ شروع کر سکتا ہے۔ JetBrains Kotlin Docs, 2025 کے مطابق، suspend فنکشنز coroutines کا بنیادی تعمیراتی بلاک ہیں، جو کال بیک کے بغیر غیر ہم آہنگی فراہم کرتے ہیں۔ ہر suspend فنکشن Continuation پر مبنی اسٹیٹ مشین میں مرتب ہوتا ہے، جو معطلی پوائنٹس کے موثر انتظام کی اجازت دیتا ہے۔

اہم نکات

  • Suspend — Kotlin کی ورڈ جو فنکشن کو روکے جانے کے قابل (غیر ہم آہنگ) کے طور پر نشان زد کرتی ہے
  • Continuation — ایک پوشیدہ پیرامیٹر جو کمپائلر اسٹیٹ محفوظ کرنے کے لیے ہر suspend فنکشن میں شامل کرتا ہے
  • معطلی پوائنٹس — وہ مقامات جہاں دوسرے suspend فنکشنز کال کیے جاتے ہیں، جہاں coroutine بغیر بلاک کیے روک سکتا ہے
  • اسٹیٹ مشین — suspend فنکشن کی داخلی نمائندگی، جہاں ہر معطلی پوائنٹ ایک علیحدہ اسٹیٹ ہے
  • صرف coroutine سے کال — suspend فنکشنز صرف دوسرے suspend فنکشن یا launch/async سے کال کیے جا سکتے ہیں

Kotlin میں suspend function کیا ہے؟

Suspend function ایک ایسا فنکشن ہے جسے suspend کیورڈ کے ساتھ اعلان کیا گیا ہے جو تھریڈ کو بلاک کیے بغیر ایک یا زیادہ پوائنٹس پر عملدرآمد روک سکتا ہے۔ دوسرے suspend فنکشن کے اندر suspend فنکشن کی ہر کال ایک ممکنہ معطلی پوائنٹ ہے۔

kotlin
suspend fun fetchUserData(): User {
    val response = httpClient.get("/user")
    return parser.parse(response)
}

Kotlin کمپائلر اس طرح کے فنکشن کو اسٹیٹ مشین میں ترجمہ کرتا ہے۔ ہر معطلی پوائنٹ (دوسرے suspend فنکشن کی کال) ایک اسٹیٹ (label) بن جاتا ہے۔ موجودہ تھریڈ اسٹیٹس کے درمیان جاری ہوتا ہے، اور منتظر آپریشن مکمل ہونے کے بعد، عملدرآمد اگلے اسٹیٹ سے دوبارہ شروع ہوتا ہے۔

تاریخ

suspend فنکشنز Kotlin 1.3 (2018) میں coroutines کے ساتھ ایک تجرباتی فیچر کے طور پر ظاہر ہوئے اور Kotlin 1.5 (2021) میں مستحکم ہو گئے۔ اس سے پہلے، Kotlin/Java میں غیر ہم آہنگی کال بیک، RxJava اور CompletableFuture کے ذریعے حاصل کی جاتی تھی۔ suspend فنکشنز نے لکیری نحو اور خودکار تھریڈ مینجمنٹ کے ساتھ ایک متبادل پیش کیا۔

suspend فنکشنز کیسے کام کرتے ہیں: Continuation اور اسٹیٹ مشین

suspend فنکشنز کی داخلی کارروائی کو سمجھنا coroutines کے ساتھ صحیح طریقے سے کام کرنے کی کلید ہے۔ عام فنکشنز کے برعکس، ہر suspend فنکشن Continuation انٹرفیس کے ساتھ ایک کلاس میں مرتب ہوتا ہے۔

Continuation — پوشیدہ پیرامیٹر

Kotlin کمپائلر ہر suspend فنکشن کے پیرامیٹر کی فہرست کے آخر میں Continuation قسم کا ایک پیرامیٹر شامل کرتا ہے۔ Continuation میں شامل ہے:

  • context — CoroutineContext (ڈسپیچر، job، سیاق و سباق کے عناصر)
  • resumeWith — نتیجہ یا استثنا کے ساتھ عملدرآمد دوبارہ شروع کرنے کا طریقہ
  • label — اسٹیٹ مشین میں موجودہ اسٹیٹ کا اشاریہ

اسٹیٹ مشین کی مثال

فرض کریں کہ ہمارے پاس دوسرے suspend فنکشنز کی دو کالوں والا ایک suspend فنکشن ہے:

kotlin
suspend fun process() {
    val a = stepOne()
    val b = stepTwo(a)
    println(b)
}

کمپائلر اسے لیبلز کے ساتھ اسٹیٹ مشین میں تبدیل کرتا ہے:

kotlin
// Simplified generated code representation
fun process(cont: Continuation<Unit>): Any? {
    val cont = cont as ProcessContinuation
    when (cont.label) {
        0 -> {
            cont.label = 1
            if (stepOne(cont) == COROUTINE_SUSPENDED) return COROUTINE_SUSPENDED
        }
        1 -> {
            cont.label = 2
            val a = cont.result as TypeA
            if (stepTwo(a, cont) == COROUTINE_SUSPENDED) return COROUTINE_SUSPENDED
        }
        2 -> {
            println(cont.result)
            Unit
        }
    }
}

اہم مشاہدہ: اگر فنکشن COROUTINE_SUSPENDED لوٹاتا ہے، تو موجودہ تھریڈ جاری ہو جاتا ہے۔ جب غیر ہم آہنگ آپریشن مکمل ہوتا ہے، Continuation.resumeWith کال کیا جاتا ہے اور اسٹیٹ مشین اگلے لیبل سے جاری رہتی ہے۔

suspend فنکشن کا نحو: اعلان اور طلب

suspend فنکشن کا اعلان عام فنکشن سے مختلف نہیں ہے، سوائے fun سے پہلے suspend کیورڈ کے۔ صرف ایک پابندی ہے: suspend فنکشن صرف coroutine یا کسی دوسرے suspend فنکشن سے کال کیا جا سکتا ہے۔

بنیادی اعلان

kotlin
suspend fun delayAndReturn(ms: Long): String {
    delay(ms)
    return "Done after ${ms}ms"
}

اس مثال میں، delay بھی ایک suspend فنکشن ہے جو تھریڈ کو بلاک کیے بغیر مخصوص ملی سیکنڈز کے لیے coroutine کو روکتا ہے۔ تاخیر کے بعد، عملدرآمد دوبارہ شروع ہوتا ہے۔

coroutine سے کال کرنا

kotlin
fun main() = runBlocking {
    val result = delayAndReturn(1000)
    println(result)
}

runBlocking عام دنیا اور coroutines کے درمیان ایک پل بناتا ہے۔ lambda کے اندر، کسی بھی suspend فنکشن کو کال کیا جا سکتا ہے۔

suspend lambdas اور فنکشنل اقسام

Kotlin فنکشنل اقسام کے suspend ورژنز کو سپورٹ کرتا ہے — suspend () -> T اور suspend (A) -> B۔ یہ اعلیٰ ترتیب کے فنکشنز میں غیر ہم آہنگ lambdas منتقل کرنے کی اجازت دیتا ہے:

kotlin
suspend fun  withRetry(
    retries: Int = 3,
    block: suspend () -> T
): T {
    repeat(retries - 1) {
        try { return block() }
        catch (_: Exception) { delay(100) }
    }
    return block()
}

withRetry فنکشن ایک suspend lambda لیتا ہے اور غلطیوں پر اس کے عملدرآمد کی دوبارہ کوشش کرتا ہے۔ یہ دوبارہ کوشش کے ساتھ نیٹ ورک کی درخواستوں کے لیے ایک عام نمونہ ہے۔

suspend فنکشنز عام فنکشنز سے کیسے مختلف ہیں

suspend اور عام فنکشنز کے درمیان فرق صرف ایک موڈیفائر شامل کرنے سے آگے بڑھتا ہے۔ آئیے اہم فرقوں کو دیکھتے ہیں۔

خصوصیتعام فنکشنsuspend فنکشن
عملدرآمد کا تھریڈمکمل ہونے تک تھریڈ کو بلاک کرتا ہےتھریڈ جاری کر سکتا ہے اور بعد میں دوبارہ شروع کر سکتا ہے
کمپائلر پیرامیٹرزصرف مخصوص کردہ پیرامیٹرزآخر میں پوشیدہ Continuation
عام فنکشن سے کالہاںنہیں
اسٹیکطبعی تھریڈ اسٹیکہیپ میں اسٹیٹ مشین + پوائنٹس کے درمیان طبعی اسٹیک
واپسی کی قیمتبراہ راست قیمتقیمت یا COROUTINE_SUSPENDED
کارکردگیکم سے کم اضافی لاگت~چند نینو سیکنڈز فی اسٹیٹ مشین (Kotlin 1.9+)

suspend فنکشنز کو عام فنکشنز سے کیوں نہیں بلا یا جا سکتا

عام فنکشن میں Continuation نہیں ہوتا — اس کے پاس اسٹیٹ محفوظ کرنے کی جگہ نہیں اور عملدرآمد دوبارہ شروع کرنے کے لیے کچھ نہیں۔ اگر آپ کو عام فنکشن سے suspend فنکشن کال کرنے کی ضرورت ہے، تو runBlocking (ٹیسٹ کے لیے) یا CoroutineScope.launch (زندگی کے چکر سے آگاہی کے ساتھ پروڈکشن کے لیے) استعمال کریں۔

Android میں suspend فنکشن کی مثالیں

آئیے Kotlin کے ساتھ Android ایپس میں suspend فنکشن استعمال کرنے کے تین حقیقی منظرنامے دیکھتے ہیں۔

مثال 1: suspend سوالات کے ساتھ Room DAO

Room براہ راست suspend فنکشنز کو سپورٹ کرتا ہے — سوال خود بخود پس منظر کے تھریڈ میں عمل میں آتا ہے:

kotlin
@Dao
interface UserDao {
    @Query("SELECT * FROM users WHERE id = :id")
    suspend fun getUser(id: Int): User?

    @Insert
    suspend fun insertUser(user: User)
}

Room اندرونی طور پر سوال کو عمل میں لانے کے لیے Dispatchers.IO استعمال کرتا ہے، اور نتیجہ اس ڈسپیچر پر واپس کیا جاتا ہے جہاں suspend فنکشن کال کیا گیا تھا۔

مثال 2: اسکرین لوڈنگ کے لیے suspend فنکشنز کی ترکیب

kotlin
class ProfileViewModel : ViewModel() {
    private val repo = ProfileRepository()

    fun loadProfile(id: String) {
        viewModelScope.launch {
            val profile = repo.getProfile(id)
            _profile.value = profile
        }
    }
}

ViewModelScope.launch ایک coroutine بناتا ہے، جس کے اندر getProfile suspend فنکشن کال کیا جاتا ہے۔ نتیجہ حاصل کرنے کے بعد، یوزر انٹرفیس مرکزی تھریڈ پر اپ ڈیٹ ہوتا ہے۔

مثال 3: ترتیب وار غیر ہم آہنگ مراحل

kotlin
suspend fun placeOrder(cart: Cart): OrderResult {
    val validated = validateCart(cart)
    val payment = processPayment(validated)
    val receipt = sendReceipt(payment)
    return receipt
}

تین suspend فنکشنز ترتیب وار عمل میں آتے ہیں۔ ہر مرحلے پر، coroutine تھریڈ کو بلاک کیے بغیر روک سکتا ہے۔ اگر کوئی مرحلہ استثنا پھینکتا ہے، تو بقیہ مراحل عمل میں نہیں آتے، جو غلط آرڈر کی حالتوں سے بچاتا ہے۔

suspend فنکشنز کے ساتھ کام کرتے وقت عام غلطیاں

تجربہ کار Kotlin ڈویلپر بھی suspend فنکشنز ڈیزائن کرتے وقت غلطیاں کرتے ہیں۔ آئیے سب سے عام غلطیاں دیکھتے ہیں۔

غلطی 1: suspend کے اندر بلاک کرنے والی کالیں

suspend فنکشن کوڈ کو خود بخود غیر ہم آہنگ نہیں بناتا۔ Thread.sleep()، InputStream.read() اور دیگر بلاک کرنے والی کالیں پھر بھی تھریڈ کو بلاک کریں گی۔ بلاک کرنے والی کارروائیوں کو لپیٹنے کے لیے withContext(Dispatchers.IO) استعمال کریں۔

غلطی 2: بغیر ضرورت کے suspend فنکشنز بنانا

اگر کوئی فنکشن دوسرے suspend فنکشنز کو کال نہیں کرتا اور غیر ہم آہنگ کارروائیاں نہیں کرتا — تو suspend موڈیفائر بے کار ہے۔ یہ اسٹیٹ مشین پر اضافی لاگت ڈالتا ہے اور کال کرنے کے سیاق و سباق کو محدود کرتا ہے۔ فنکشن کو صرف اس وقت suspend بنائیں جب وہ واقعی رکتا ہو۔

غلطی 3: CancellationException کو نظر انداز کرنا

جب coroutine منسوخ ہوتا ہے، suspend فنکشنز CancellationException پھینکتے ہیں۔ اسے بغیر سوچے نہ پکڑیں — آپ کال کرنے والے کوڈ کو منسوخی کو صحیح طریقے سے مکمل کرنے کی صلاحیت سے محروم کر رہے ہیں۔ اگر آپ کو حتمی کارروائی کرنے کی ضرورت ہے، تو finally بلاک اور NonCancellable استعمال کریں۔

kotlin
suspend fun safeOperation() {
    try {
        doWork()
    } finally {
        withContext(NonCancellable) {
            cleanup()
        }
    }
}

finally بلاک ہمیشہ عمل میں آتا ہے، منسوخی پر بھی، اور NonCancellable یقینی بناتا ہے کہ صفائی میں خلل نہ پڑے۔

غلطی 4: کال بیک سے suspend فنکشنز کال کرنا

آپ coroutine بنائے بغیر براہ راست کال بیک سے suspend فنکشن کال نہیں کر سکتے۔ کال بیک اسٹائل کو coroutines کے مطابق ڈھالنے کے لیے suspendCoroutine یا suspendCancellableCoroutine استعمال کریں۔

اکثر پوچھے گئے سوالات

کیا suspend فنکشن میں کوئی معطلی پوائنٹ نہیں ہو سکتا؟

ہاں، تکنیکی طور پر suspend فنکشن دوسرے suspend فنکشنز کو کال نہیں کر سکتا۔ کمپائلر ایک اسٹیٹ (label 0) کے ساتھ اسٹیٹ مشین بنائے گا۔ تاہم، اس طرح کے فنکشن کا کوئی عملی فائدہ نہیں — یہ عام فنکشن کی طرح چلتا ہے لیکن اضافی لاگت کے ساتھ۔ بغیر ضرورت کے suspend استعمال نہ کریں۔

suspend فنکشنز کو ڈیبگ کیسے کریں؟

Kotlin kotlinx-coroutines-debug فراہم کرتا ہے — DebugProbes اور coroutine ٹریسنگ ٹولز کے ساتھ ایک لائبریری۔ Android Studio میں Arctic Fox سے، ڈیبگر میں ایک بلٹ ان Coroutines ٹیب ہے جو فعال coroutines، ان کی حالت اور معطلی پوائنٹس دکھاتا ہے۔

کیا معطلی پوائنٹس کی تعداد کارکردگی کو متاثر کرتی ہے؟

ہر معطلی پوائنٹ اسٹیٹ مشین میں ایک نیا اسٹیٹ بناتا ہے۔ زیادہ تر ایپلیکیشنز کے لیے، ایک پوائنٹ کی اضافی لاگت چند نینو سیکنڈز ہے (Kotlin 1.9+)۔ صرف لوپ میں دسیوں ہزار پوائنٹس کے ساتھ آپ کو آپریشنز کو یکجا کرنے یا sequence/flow استعمال کرنے پر غور کرنا چاہیے۔

suspend فنکشن دوسری زبانوں میں async/await سے کیسے مختلف ہے؟

Kotlin میں، suspend ایک فنکشن قسم کا موڈیفائر ہے، واپسی کی قیمت کا نشان نہیں (جیسے C# میں async)۔ کوئی بھی suspend فنکشن کسی بھی پیرامیٹر اور واپسی کی قسم رکھ سکتا ہے، اور اس کی کال نحوی طور پر عام فنکشن کال سے مختلف نہیں — کال کی جگہ پر کوئی await آپریٹر نہیں ہے۔

کال بیک فنکشن کو suspend میں کیسے تبدیل کریں؟

موافقت کے لیے suspendCancellableCoroutine استعمال کریں۔ اندر، آپ ایک کال بیک رجسٹر کرتے ہیں جو continuation.resume() کو کال کرتا ہے، اور اگر کال بیک سبسکرپشن منسوخی کو سپورٹ کرتا ہے تو منسوخی کا ٹوکن واپس کرتے ہیں۔ یہ پرانے Android API کو لپیٹنے کا معیاری نمونہ ہے۔

خلاصہ

  • Suspend function — Continuation میکانزم کے ذریعے تھریڈ کو بلاک کیے بغیر عملدرآمد روک سکنے والا suspend موڈیفائر والا فنکشن
  • اسٹیٹ مشین — Kotlin بائٹ کوڈ میں suspend فنکشن کی داخلی نمائندگی، جہاں ہر معطلی پوائنٹ ایک لیبل کے ساتھ علیحدہ اسٹیٹ
  • Continuation — ایک پوشیدہ پیرامیٹر جس میں coroutine سیاق و سباق اور عملدرآمد دوبارہ شروع کرنے کے لیے resumeWith طریقہ شامل ہے
  • صرف coroutine سے کال — suspend فنکشنز runBlocking یا CoroutineScope کے بغیر عام فنکشنز سے قابل رسائی نہیں
  • بلاک کرنے والی کارروائیاں suspend کے اندر withContext(Dispatchers.IO) کی ضرورت ہوتی ہیں — ورنہ تھریڈ بلاک ہوتا ہے
  • Room اور Retrofit مقامی طور پر suspend فنکشنز کو سپورٹ کرتے ہیں، خود بخود پس منظر کے تھریڈز کا انتظام کرتے ہیں
  • CancellationException — finally + NonCancellable کے ذریعے منسوخی کو سنبھالیں، CancellationException کو بغیر سوچے نہ پکڑیں

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں