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 थ्रेड कब नहीं बदलता

Dispatchers.Main withContext(Dispatchers.Main) के अंदर स्विच नहीं करता — Kotlin Coroutines कॉन्टेक्स्ट की समानता को पहचानता है और अनावश्यक संचालन को छोड़ देता है। इसी तरह, withContext(Dispatchers.Default) पहले से 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 को लपेटता है और उसके डिस्पैचर को बदलता है। यदि नया डिस्पैचर वर्तमान से भिन्न है, तो निष्पादन निलंबित हो जाता है, ब्लॉक संबंधित थ्रेड पूल को भेजा जाता है, और पूरा होने के बाद — मूल कॉन्टेक्स्ट के साथ फिर से शुरू होता है।

अनुकूलन: कॉन्टेक्स्ट मेल खाने पर फ़ास्ट-पाथ

जब 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 एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

परियोजना पर चर्चा करें

यह भी पढ़ें