withContext: یہ کیا ہے، سیاق و سباق کی تبدیلی اور کوروٹین میں کام

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

withContext — ایک کوروٹین کے اندر سیاق و سباق تبدیل کرنے والا فنکشن ہے جو کوڈ کے دیے گئے بلاک کے لیے عارضی طور پر تھریڈ یا ڈسپیچر تبدیل کرتا ہے اور نتیجہ اصل سیاق و سباق میں واپس لاتا ہے۔ JetBrains, 2025 کے مطابق، withContext نیٹ ورک کی درخواستوں اور ڈسک آپریشنز کے لیے سب سے زیادہ استعمال ہونے والے کوروٹین ٹولز میں سے ایک ہے۔ فنکشن اس بات کی ضمانت دیتا ہے کہ بلاک مکمل ہونے کے بعد کوروٹین اصل ڈسپیچر پر عمل جاری رکھے، جس سے اتفاقی تھریڈ سیفٹی کی غلطیاں روکی جاتی ہیں۔

اہم نکات

  • withContext — ایک معطل کرنے والا فنکشن جو دیے گئے کوڈ بلاک کے لیے CoroutineContext تبدیل کرتا ہے اور نتیجہ واپس لاتا ہے
  • Dispatchers.IO — نیٹ ورک اور ڈسک آپریشنز کے لیے بیک گراؤنڈ تھریڈ پر سوئچ کرنے کا عام آرگومینٹ
  • Dispatchers.Main — اصل سیاق و سباق جس میں withContext بلاک مکمل ہونے کے بعد خود بخود عمل واپس لاتا ہے
  • ترتیب وار کالز — withContext کوڈ کو ترتیب وار انجام دیتا ہے، launch اور async کے برعکس، جو آپریشنز کی ترتیب پر کنٹرول آسان بناتا ہے
  • Val نتیجہ — withContext لیمبڈا کی آخری لائن میں return کے ذریعے براہ راست ویلیو لوٹاتا ہے، بغیر await یا join کے

Kotlin میں withContext کیا ہے؟

withContext kotlinx.coroutines پیکیج سے ایک معطل کرنے والا فنکشن ہے جو کوڈ کے دیے گئے بلاک کو ایک مخصوص CoroutineContext میں انجام دیتا ہے اور نتیجہ اصل سیاق و سباق میں واپس لاتا ہے۔ فنکشن کا دستخط اس طرح ہے:

kotlin
suspend fun  withContext(
    context: CoroutineContext,
    block: suspend CoroutineScope.() -> T
): T

context پیرامیٹر کسی بھی CoroutineContext کو قبول کرتا ہے — عام طور پر معیاری Dispatchers.IO، Dispatchers.Default یا Dispatchers.Main میں سے ایک۔ بلاک اس سیاق و سباق میں عملدرآمد ہوتا ہے، اور نتیجہ وہاں واپس آتا ہے جہاں سے withContext کو کال کیا گیا تھا۔

اہم خصوصیت: خودکار واپسی

لیمبڈا مکمل ہونے کے بعد، withContext یقینی طور پر عملدرآمد کو اصل ڈسپیچر پر واپس لاتا ہے۔ اس کا مطلب ہے کہ ڈویلپر کو بیک گراؤنڈ آپریشن کے بعد دستی طور پر withContext(Dispatchers.Main) کال کرنے کی ضرورت نہیں ہے — واپسی خود بخود ہوتی ہے۔ یہ رویہ Kotlin Coroutines تصریح میں ورژن 1.3 سے دستاویزی ہے۔

withContext کہاں استعمال ہوتا ہے

Android ڈویلپمنٹ withContext کے استعمال کا بنیادی شعبہ ہے۔ ایک عام منظرنامہ: ViewModel مرکزی تھریڈ پر ایک کوروٹین شروع کرتا ہے، اس کے اندر نیٹ ورک کی درخواست کے لیے withContext(Dispatchers.IO) کال کرتا ہے، اور Main پر خودکار واپسی کے بعد نتیجہ UI کو اپ ڈیٹ کرنے کے لیے استعمال ہوتا ہے۔ یہ طریقہ MVVM آرکیٹیکچر کی بنیاد ہے اور Google کے سرکاری کوروٹین گائیڈ میں تجویز کیا گیا ہے۔

withContext کیسے کام کرتا ہے: ڈسپیچرز تبدیل کرنا

withContext کو سمجھنے کے لیے، آپ کو CoroutineContext اور اس کے اہم جز — ڈسپیچر کو سمجھنا ہوگا۔ ہر کوروٹین میں سیاق و سباق کے عناصر کا ایک سیٹ ہوتا ہے، جن میں سے ڈسپیچر یہ طے کرتا ہے کہ کوڈ کس تھریڈ یا تھریڈ پول پر چلے گا۔

withContext کے لیے معیاری ڈسپیچرز

ڈسپیچرمقصدپول کا سائز
Dispatchers.Mainمرکزی UI تھریڈ (Android, JavaFX, Swing)1 (مرکزی تھریڈ)
Dispatchers.IOڈسک اور نیٹ ورک آپریشنز64 تھریڈ (حد بڑھتی ہے)
Dispatchers.DefaultCPU گنتی کے حسابmax(2, کور کی تعداد)
Dispatchers.Unconfinedکوئی مقررہ تھریڈ نہیںلامحدود

یہ سمجھنا ضروری ہے کہ withContext نیا کوروٹین نہیں بناتا — یہ صرف موجودہ کوروٹین کا سیاق و سباق تبدیل کرتا ہے۔ یہ launch اور async سے بنیادی فرق ہے، جو نئے کوروٹین بناتے ہیں۔ withContext کا اندرونی نفاذ بہتر بنایا گیا ہے: اگر درخواست کردہ سیاق و سباق موجودہ سے مطابقت رکھتا ہے، تو کوئی تبدیلی نہیں ہوتی — فنکشن اسی ڈسپیچر پر عملدرآمد کرتا ہے۔

withContext کب تھریڈ تبدیل نہیں کرتا

withContext(Dispatchers.Main) کے اندر Dispatchers.Main تبدیلی کا سبب نہیں بنتا — Kotlin Coroutines سیاق و سباق کی مماثلت کو پہچانتا ہے اور غیر ضروری آپریشن کو چھوڑ دیتا ہے۔ اسی طرح، پہلے سے Default پر چلنے والے کوروٹین کے اندر withContext(Dispatchers.Default) اضافی بوجھ نہیں بناتا۔ یہ اصلاح ContinuationInterceptor میں نافذ کی گئی ہے۔

withContext بمقابلہ launch اور async: کب کیا چنیں

ابتدائی افراد اکثر withContext کو launch اور async کے ساتھ الجھاتے ہیں، کیونکہ تینوں فنکشن کوروٹین اور سیاق و سباق کے ساتھ کام کرتے ہیں۔ تاہم، ان کا مقصد بنیادی طور پر مختلف ہے۔

تینوں فنکشن کا موازنہ

خصوصیتwithContextlaunchasync
نیا کوروٹین بناتا ہےنہیںہاںہاں
نتیجہ لوٹاتا ہےہاں (T براہ راست)نہیں (Job)ہاں (Deferred<T>)
عملدرآمدترتیب وارمتوازیمتوازی
نتیجے کا انتظارخودکارjoin()await()
عام استعمال کا معاملہڈسپیچر تبدیل کرنافائر-اینڈ-فورگیٹمتوازی حسابات

انتخاب کا قاعدہ

اگر آپ کو بیک گراؤنڈ تھریڈ پر ایک آپریشن انجام دینا ہے اور نتیجہ حاصل کرنا ہے — withContext استعمال کریں۔ اگر آپ کو کئی آزاد آپریشن متوازی طور پر چلانے ہیں — await کے ساتھ async استعمال کریں۔ اگر نتیجہ کی ضرورت نہیں ہے (لاگنگ، کیش لکھنا) — launch استعمال کریں۔ Google Android آرکیٹیکچر میں Repository پرت کے لیے withContext کو ترجیحی ٹول کے طور پر تجویز کرتا ہے۔

withContext کے ساتھ کوڈ کی مثالیں

آئیے Kotlin Android ایپلیکیشنز میں withContext استعمال کرنے کے تین عملی منظرنامے دیکھتے ہیں۔ ہر مثال ایک مخصوص کام اور صحیح پیٹرن کو ظاہر کرتی ہے۔

مثال 1: Repository میں نیٹ ورک کی درخواست

ViewModel Main پر کوروٹین سے ریپوزٹری طریقہ کال کرتا ہے۔ اندر، withContext(Dispatchers.IO) HTTP درخواست انجام دیتا ہے، اور نتیجہ خود بخود واپس آتا ہے:

kotlin
class UserRepository(
    private val api: UserApi
) {
    suspend fun getUser(id: String): User {
        return withContext(Dispatchers.IO) {
            api.fetchUser(id)
        }
    }
}

ViewModel میں کوروٹین getUser کو کسی بھی عام معطل کرنے والے فنکشن کی طرح کال کرتا ہے — بغیر ڈسپیچر کی واضح وضاحت کے۔ withContext تھریڈ تبدیل کرنے کی تفصیلات چھپاتا ہے۔

مثال 2: دو ترتیب وار بیک گراؤنڈ آپریشن

جب آپ کو ایک کے بعد ایک کئی IO آپریشن کرنے کی ضرورت ہوتی ہے، withContext انہیں ایک بلاک میں یکجا کرتا ہے۔ یہ ہر آپریشن کو علیحدہ withContext میں لپیٹنے سے زیادہ موثر ہے:

kotlin
suspend fun loadUserProfile(id: String): Profile {
    return withContext(Dispatchers.IO) {
        val user = api.fetchUser(id)
        val posts = api.fetchPosts(id)
        Profile(user, posts)
    }
}

دونوں آپریشن Dispatchers.IO پر چلتے ہیں، اور Profile نتیجہ غیر ضروری سیاق و سباق کی تبدیلیوں کے بغیر بنایا اور واپس کیا جاتا ہے۔ اگر آپریشن آزاد ہیں، تو متوازی عملدرآمد کے لیے async استعمال کرنا بہتر ہے۔

مثال 3: NonCancellable کے ساتھ مخلوط سیاق و سباق

کچھ منظرناموں میں، آپ کو ایسا کوڈ انجام دینے کی ضرورت ہوتی ہے جسے منسوخ نہیں کیا جا سکتا — مثال کے طور پر، اسکرین بند کرتے وقت حالت محفوظ کرنا۔ withContext + NonCancellable کا امتزاج اس کام کو حل کرتا ہے:

kotlin
withContext(Dispatchers.IO + NonCancellable) {
    cache.saveState(state)
    analytics.logEvent("state_saved")
}

آپریٹر + دو سیاق و سباق کے عناصر کو جوڑتا ہے: IO ڈسپیچر اور NonCancellable جھنڈی۔ بلاک اس وقت بھی عملدرآمد ہوتا ہے جب پیرنٹ کوروٹین منسوخ کر دیا گیا ہو — اختتامی کارروائیوں کے لیے مفید۔

پردے کے پیچھے کیا ہوتا ہے: Continuation اور اصلاح

withContext کا اندرونی نفاذ Continuation میکانزم پر مبنی ہے — Kotlin کوروٹین کا مرکزی تجرید۔ ہر معطلی پوائنٹ عملدرآمد کی حالت کو Continuation آبجیکٹ میں محفوظ کرتا ہے، اور withContext اس سے مستثنیٰ نہیں ہے۔

withContext بائٹ کوڈ کی سطح پر سیاق و سباق کیسے تبدیل کرتا ہے

Kotlin کمپائلر withContext کو kotlinx.coroutines سے withContext طریقہ کال میں ترجمہ کرتا ہے، جو اندرونی طور پر DispatchedContinuation کی ایک نئی مثال بناتا ہے۔ یہ آبجیکٹ اصل Continuation کو لپیٹتا ہے اور اس کے ڈسپیچر کو تبدیل کرتا ہے۔ اگر نیا ڈسپیچر موجودہ سے مختلف ہے، تو عملدرآمد معطل ہو جاتا ہے، بلاک متعلقہ تھریڈ پول کو بھیجا جاتا ہے، اور مکمل ہونے کے بعد — اصل سیاق و سباق کے ساتھ دوبارہ شروع ہوتا ہے۔

اصلاح: سیاق و سباق کے مماثل ہونے پر تیز راستہ (fast-path)

جب withContext کو اسی ڈسپیچر کے ساتھ کال کیا جاتا ہے جس پر کوروٹین پہلے سے چل رہا ہے، Kotlin تیز راستہ (fast-path) فعال کرتا ہے: بلاک ہم آہنگی سے عملدرآمد کرتا ہے، بغیر DispatchedContinuation بنائے اور بغیر تھریڈ پول کو بھیجے۔ یہ withContext کو ایک ہی سیاق و سباق کے ساتھ بار بار کال کرنے پر عملی طور پر مفت بنا دیتا ہے۔ JetBrains بینچ مارکس (kotlinx.coroutines 1.8) کے مطابق، تیز راستہ 0.1 µs سے کم میں مکمل ہوتا ہے۔

کارکردگی کے تحفظات

withContext کی ہر کال مختلف ڈسپیچر کے ساتھ ایک نیا DispatchedContinuation بناتی ہے اور تھریڈ تبدیل کرنے کی ضرورت ہوتی ہے — اس میں بوجھ کے لحاظ سے 1 سے 5 µs لگتے ہیں۔ زیادہ تر ایپلیکیشنز کے لیے یہ تاخیر ناقابلِ دید ہے، لیکن ہزاروں تکرار والے لوپ کے اندر، آپریشنز کو ایک withContext بلاک میں جمع کرنا مناسب ہے۔

withContext استعمال کرتے وقت عام غلطیاں

تجربہ کار ڈویلپر بھی withContext کے ساتھ کام کرتے وقت غلطیاں کرتے ہیں۔ آئیے چار سب سے عام مسائل اور انہیں روکنے کے طریقے دیکھتے ہیں۔

غلطی 1: غیر ضروری نیسٹڈ withContext

ڈویلپر اکثر آپریشنز کو ایک بلاک میں یکجا کرنے کے بجائے ہر لائن کو علیحدہ withContext میں لپیٹتے ہیں۔ مختلف ڈسپیچر کے ساتھ ہر اضافی کال اضافی بوجھ بناتی ہے۔

درست: ترتیب وار IO آپریشنز کو ایک withContext(Dispatchers.IO) { ... } میں یکجا کریں۔ اگر کچھ آپریشن CPU گنتی کے حامل ہیں — اسی بلاک کے اندر withContext(Dispatchers.Default) استعمال کریں۔

غلطی 2: متوازی کاموں کے لیے async کی بجائے withContext استعمال کرنا

withContext کوڈ کو ترتیب وار انجام دیتا ہے۔ اگر دو آزاد نیٹ ورک درخواستیں ایک withContext میں لپیٹی گئی ہیں، تو وہ ایک کے بعد ایک چلیں گی۔ متوازی عملدرآمد کے لیے، async + await استعمال کریں۔

kotlin
// ترتیب وار — سست
withContext(Dispatchers.IO) {
    val a = api.fetchA()
    val b = api.fetchB()
}

// متوازی — تیز
coroutineScope {
    val a = async { api.fetchA() }
    val b = async { api.fetchB() }
    println("${a.await()} ${b.await()}")
}

غلطی 3: اہم آپریشنز کے لیے NonCancellable بھولنا

اگر withContext کے دوران کوروٹین منسوخ کر دیا جاتا ہے، تو Dispatchers.IO پر بلاک بھی روک دیا جاتا ہے۔ ان آپریشنز کے لیے جو ہر قیمت پر مکمل ہونے چاہئیں (ڈیٹا بیس لکھنا، تجزیات بھیجنا)، withContext کو NonCancellable کے ساتھ جوڑیں۔

غلطی 4: IO بلاک کے اندر UI حالت کو اپ ڈیٹ کرنا

withContext(Dispatchers.IO) کے اندر کبھی بھی View اجزاء کو اپ ڈیٹ نہ کریں۔ withContext پورے بلاک کے مکمل ہونے تک Main پر واپس نہیں آتا۔ UI اپ ڈیٹس کو withContext کے بند ہونے والے بریکٹ کے بعد رکھیں — تب کوروٹین پہلے سے مرکزی تھریڈ پر ہوگا۔

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

withContext runBlocking سے کیسے مختلف ہے؟

withContext ایک معطل کرنے والا فنکشن ہے جو تھریڈ کو بلاک نہیں کرتا، بلکہ موجودہ کوروٹین کے اندر سیاق و سباق تبدیل کرتا ہے۔ runBlocking کوروٹین اور عام کوڈ کے درمیان ایک پل ہے جو مکمل ہونے تک موجودہ تھریڈ کو بلاک کرتا ہے۔ withContext UI تھریڈ کے لیے محفوظ ہے، runBlocking نہیں ہے۔

کیا withContext کو suspend کے بغیر استعمال کیا جا سکتا ہے؟

نہیں، withContext ایک suspend فنکشن ہے، لہذا اسے صرف کسی دوسرے suspend فنکشن یا کوروٹین (launch/async) سے کال کیا جا سکتا ہے۔ عام فنکشن سے withContext کو کال نہیں کیا جا سکتا — اس کے لیے runBlocking یا CoroutineScope کی ضرورت ہے۔

اگر withContext میں وہی ڈسپیچر پاس کیا جائے تو کیا ہوتا ہے؟

Kotlin تیز راستہ (fast-path) فعال کرتا ہے — بلاک اسی تھریڈ پر تبدیلی کے بغیر ہم آہنگی سے عملدرآمد کرتا ہے۔ اضافی بوجھ 0.1 µs سے کم ہے۔ یہ کوئی غلطی نہیں ہے، لیکن ایسی کال بے کار ہے — بغیر withContext کے کوڈ کو انجام دینا بہتر ہے۔

withContext استثنیات (exceptions) کے ساتھ کیسے کام کرتا ہے؟

withContext کے اندر استثنیات عام کوڈ کی طرح پھیلتی ہیں — try-catch کے ذریعے۔ اگر بلاک استثنیٰ پھینکتا ہے، تو یہ پیرنٹ کوروٹین میں پھیلتا ہے اور اگر ہینڈل نہ کیا گیا تو اسے منسوخ کر دیتا ہے۔ withContext کے اندر یا اس کے ارد گرد try-catch استعمال کریں۔

کیا withContext نیا کوروٹین بناتا ہے یا نہیں؟

نہیں، withContext نیا کوروٹین نہیں بناتا۔ یہ موجودہ کوروٹین استعمال کرتا ہے لیکن عارضی طور پر اس کا سیاق و سباق تبدیل کرتا ہے۔ یہ اسے launch اور async سے ممتاز کرتا ہے، جو چائلڈ کوروٹین بناتے ہیں۔ اس رویے کی تصدیق kotlinx.coroutines سورس کوڈ سے ہوتی ہے۔

خلاصہ

  • withContext — موجودہ کوروٹین کے اندر CoroutineContext تبدیل کرنے کے لیے ایک suspend فنکشن جو اصل سیاق و سباق میں خودکار واپسی کرتا ہے
  • Dispatchers.IO — withContext کے اندر نیٹ ورک کی درخواستوں اور ڈسک آپریشنز کے لیے مرکزی ڈسپیچر
  • تیز راستہ (Fast-path) — ایک Kotlin اصلاح جہاں withContext اسی ڈسپیچر کے ساتھ اضافی بوجھ کے بغیر ہم آہنگی سے عملدرآمد کرتا ہے
  • متوازی کام async/await کی ضرورت ہے، withContext کی نہیں — withContext کوڈ کو ترتیب وار انجام دیتا ہے
  • NonCancellable — withContext کے اندر اہم آپریشنز کے لیے ایک جھنڈی جو کوروٹین منسوخ ہونے پر رکاوٹ نہیں ہونی چاہیے
  • Repository پرت — Google رہنما خطوط کے مطابق Android آرکیٹیکچر میں withContext کے لیے تجویز کردہ جگہ
  • Continuation — وہ میکانزم جس پر Kotlin بائٹ کوڈ کی سطح پر withContext میں سیاق و سباق کی تبدیلی مبنی ہے

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

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

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

مزید پڑھیں