CoroutineScope — यह क्या है, जीवनचक्र और कोरूटीन में कार्य

लेखक: IT Sectr प्रकाशित: 2026-06-22 पढ़ने का समय: 10 मिनट

CoroutineScope एक Kotlin इंटरफ़ेस है जो कोरूटीन के जीवनचक्र को परिभाषित करता है और नए कोरूटीन चलाने के लिए संदर्भ प्रदान करता है। Kotlin दस्तावेज़ीकरण, 2025 के अनुसार, प्रत्येक CoroutineScope इंस्टेंस में CoroutineContext होता है और यह उसके अंदर चलाए गए सभी कोरूटीन को प्रबंधित करता है। जब scope रद्द (cancel) होता है, तो सभी चाइल्ड कोरूटीन स्वचालित रूप से रद्द हो जाते हैं, जिससे मेमोरी लीक रुकती है।

मुख्य बातें

  • CoroutineScope — एक ही CoroutineContext फ़ील्ड वाला इंटरफ़ेस, जो कोरूटीन का जीवनचक्र परिभाषित करता है
  • Job — रद्दीकरण के लिए जिम्मेदार संदर्भ तत्व: scope रद्द करने से सभी चाइल्ड कोरूटीन रद्द हो जाते हैं
  • संरचनात्मक समवर्तीता — वह सिद्धांत जिसमें चाइल्ड कोरूटीन पैरेंट scope से बंधे होते हैं
  • GlobalScope — पूरे ऐप्लिकेशन के लिए scope, जो मेमोरी लीक के जोखिम के कारण अनुशंसित नहीं है
  • supervisorScope — एक विशेष scope जिसमें एक चाइल्ड कोरूटीन को रद्द करने से बाकी रद्द नहीं होते

Kotlin में CoroutineScope क्या है?

CoroutineScope kotlinx.coroutines लाइब्रेरी का एक मूलभूत इंटरफ़ेस है जो कोरूटीन के लिए कंटेनर का काम करता है। यह कोरूटीन जीवनचक्र की सीमाएँ परिभाषित करता है: जब scope पूरा होता है, तो उसके अंदर के सभी कोरूटीन स्वचालित रूप से रद्द हो जाते हैं।

kotlin
public interface CoroutineScope {
    public val coroutineContext: CoroutineContext
}

इंटरफ़ेस में सिर्फ एक फ़ील्ड है — coroutineContext। इसके माध्यम से, scope उसके अंदर चलाए गए सभी कोरूटीन के लिए डिस्पैचर (Dispatcher), जॉब (Job), अपवाद हैंडलर और अन्य संदर्भ तत्व प्रदान करता है।

kotlinx.coroutines लाइब्रेरी में भूमिका

कोरूटीन चलाने वाले सभी फ़ंक्शन — launch, async, runBlocking — CoroutineScope पर एक्सटेंशन फ़ंक्शन हैं। इसका मतलब है कि इन्हें केवल scope ऑब्जेक्ट उपलब्ध होने पर ही कॉल किया जा सकता है। यह डिज़ाइन सुनिश्चित करता है कि प्रत्येक कोरूटीन का एक स्पष्ट रूप से परिभाषित पैरेंट और जीवनचक्र हो।

CoroutineScope कहाँ उपयोग होता है

Android में, प्रत्येक आर्किटेक्चरल कंपोनेंट का अपना scope होता है: ViewModel के लिए viewModelScope, Activity/Fragment के लिए lifecycleScope। सर्वर ऐप्लिकेशन में, scope को HTTP अनुरोध या डेटाबेस कनेक्शन पूल से बाँधा जा सकता है।

CoroutineScope कैसे काम करता है: Job और संरचनात्मक समवर्तीता

CoroutineScope की आंतरिक कार्यप्रणाली को समझने के लिए Job की अवधारणा और संरचनात्मक समवर्तीता के सिद्धांत से परिचित होना आवश्यक है।

Job — कोरूटीन का कार्य

प्रत्येक कोरूटीन चलने पर एक Job ऑब्जेक्ट (या async के लिए Deferred) लौटाता है। Job एक सीमित जीवनचक्र वाले कार्य का प्रतिनिधित्व करता है: New, Active, Completing, Completed, Cancelling, Cancelled। Job ऑब्जेक्ट एक पेड़ संरचना बनाते हैं:

  • पैरेंट Job — वह scope जिसमें कोरूटीन चलाया गया
  • चाइल्ड Job — launch/async के माध्यम से चलाया गया प्रत्येक कोरूटीन
  • पैरेंट का रद्दीकरण → सभी चाइल्ड का रद्दीकरण
  • चाइल्ड में अपवाद → पैरेंट का रद्दीकरण (supervisorScope को छोड़कर)

संरचनात्मक समवर्तीता का सिद्धांत

संरचनात्मक समवर्तीता Kotlin Coroutines का एक प्रमुख आर्किटेक्चरल सिद्धांत है, जिसमें कोरूटीन का जीवनचक्र उसके scope के जीवनचक्र से बंधा होता है। यह “फायर-एंड-फ़ॉरगेट” मॉडल के विपरीत है, जहाँ कोरूटीन scope के पूरा होने के बाद भी जीवित रहता है। संरचनात्मक समवर्तीता के लाभ:

  • पूर्वानुमानित जीवनचक्र — जब scope पूरा होता है, सभी कोरूटीन रुक जाएँगे
  • स्वचालित त्रुटि प्रबंधन — किसी भी चाइल्ड कोरूटीन में अपवाद scope पर फैलता है
  • कोई मेमोरी लीक नहीं — scope पूरा होने के बाद कोई कोरूटीन नहीं चलता
  • स्पष्ट पदानुक्रम — कोड समानांतर संचालन की तार्किक संरचना दर्शाता है

CoroutineScope का जीवनचक्र

जब scope.cancel() कॉल किया जाता है, तो scope का Job Cancelled स्थिति में चला जाता है, जो सभी चाइल्ड Job को पुनरावर्ती रूप से रद्द करता है। रद्दीकरण के बाद, scope का पुन: उपयोग केवल नया CoroutineScope इंस्टेंस बनाकर ही किया जा सकता है।

CoroutineScope बनाना और कॉन्फ़िगर करना

आप CoroutineScope को फ़ैक्टरी फ़ंक्शन के माध्यम से या अपनी क्लास में इंटरफ़ेस लागू करके बना सकते हैं। दोनों तरीकों को देखते हैं।

फ़ैक्टरी फ़ंक्शन CoroutineScope()

kotlin
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())

scope.launch {
    println("Running on ${Thread.currentThread().name}")
}

फ़ैक्टरी फ़ंक्शन CoroutineContext लेता है और निर्दिष्ट संदर्भ के साथ scope बनाता है। उदाहरण CPU-गहन कार्यों के लिए Dispatchers.Default और SupervisorJob का उपयोग करता है, जो चाइल्ड कोरूटीन के बीच अपवादों को अलग करता है।

कंपोज़िशन के माध्यम से इंटरफ़ेस लागू करना

kotlin
class MyRepository {
    private val scope = CoroutineScope(Dispatchers.IO + Job())

    suspend fun fetchData(): Data = scope.async {
        api.getData()
    }.await()

    fun cleanup() {
        scope.cancel()
    }
}

हम scope को क्लास फ़ील्ड के रूप में संग्रहीत करते हैं और इसे रद्द करने के लिए मैन्युअल रूप से cleanup कॉल करते हैं। यह दृष्टिकोण प्रबंधित जीवनचक्र वाले कंपोनेंट — जैसे रिपॉजिटरी या मैनेजर — के लिए उपयुक्त है।

डेलिगेशन के माध्यम से कार्यान्वयन

Kotlin by कीवर्ड के माध्यम से CoroutineScope कार्यान्वयन को डेलिगेट करने की अनुमति देता है:

kotlin
class DataLoader : CoroutineScope by CoroutineScope(Dispatchers.IO) {
    fun load() {
        launch {
            // coroutine runs in DataLoader scope
        }
    }
}

यह दृष्टिकोण तब सुविधाजनक है जब क्लास स्वयं एक scope है और कोरूटीन चलाने के तरीके प्रदान करना चाहती है। लेकिन सावधान रहें: क्लास CoroutineScope के सभी तरीकों को इनहेरिट करती है, जिसमें cancel भी शामिल है, जो एनकैप्सुलेशन को तोड़ सकता है।

GlobalScope बनाम कस्टम CoroutineScope

GlobalScope पूरे ऐप्लिकेशन के लिए एक सिंगलटन CoroutineScope है। प्रोडक्शन कोड में इसका उपयोग आधिकारिक रूप से अनुशंसित नहीं है।

GlobalScope की समस्याएँ

  • संरचनात्मक समवर्तीता का अभाव — GlobalScope में कोरूटीन कंपोनेंट जीवनचक्र से बंधे नहीं होते
  • मेमोरी लीक — Activity/Fragment बंद होने के बाद भी कोरूटीन चलता रह सकता है
  • कठिन परीक्षण — GlobalScope को टेस्ट में बदला नहीं जा सकता
  • अनियंत्रित संसाधन खपत — कई कोरूटीन अपेक्षा से अधिक समय तक चल सकते हैं

GlobalScope कब उचित है

JetBrains GlobalScope को केवल दुर्लभ परिदृश्यों में अनुमति देता है: एप्लिकेशन-स्तरीय पृष्ठभूमि प्रक्रियाएँ जो सभी Activities बंद होने के बाद भी चलनी चाहिए (जैसे डेटा सिंक्रोनाइज़ेशन, एनालिटिक्स)। लेकिन इन मामलों में भी, CoroutineScope(SupervisorJob()) के साथ अपना खुद का scope बनाना बेहतर है।

अनुशंसा

हमेशा कस्टम CoroutineScope का उपयोग करें जिसमें स्पष्ट जीवनचक्र प्रबंधन हो। Android में, ये viewModelScope और lifecycleScope हैं। सर्वर ऐप्लिकेशन में, प्रत्येक अनुरोध या कनेक्शन पूल के लिए scope बनाएँ।

coroutineScope बनाम supervisorScope: क्या अंतर है

दोनों फ़ंक्शन सस्पेंड फ़ंक्शन हैं जो समानांतर कार्यों के लिए अस्थायी scope बनाते हैं, लेकिन अपवादों के साथ उनका व्यवहार मौलिक रूप से भिन्न होता है।

विशेषताcoroutineScopesupervisorScope
त्रुटि पर व्यवहारचाइल्ड कोरूटीन में अपवाद बाकी सभी को रद्द करता हैचाइल्ड कोरूटीन में अपवाद बाकी को नहीं रद्द करता
त्रुटि प्रसारहाँ, पहला अपवाद बाहर फैलता हैहाँ, पहला अपवाद बाहर फैलता है
डिफ़ॉल्ट JobJob() — चाइल्ड पैरेंट से बंधे हैंSupervisorJob() — चाइल्ड एक-दूसरे पर निर्भर नहीं
विशिष्ट उपयोग-मामलाएकाधिक चरणों का परमाणु संचालनस्वतंत्र समानांतर कार्य (UI लोड)

coroutineScope कब चुनें

coroutineScope का उपयोग करें जब कई समानांतर संचालन एक एकल परमाणु संचालन बनाते हैं। उदाहरण के लिए, तीन सर्वरों से डेटा लोड करना: यदि एक अनुरोध विफल होता है, तो बाकी अर्थहीन हैं।

kotlin
suspend fun loadProductPage(): ProductPage = coroutineScope {
    val product = async { api.getProduct() }
    val reviews = async { api.getReviews() }
    ProductPage(product.await(), reviews.await())
}

यदि getProduct या getReviews अपवाद फेंकता है — दोनों कोरूटीन रद्द हो जाते हैं, और अपवाद कॉल करने वाले कोड में फैल जाता है।

supervisorScope कब चुनें

supervisorScope का उपयोग करें जब समानांतर संचालन एक-दूसरे पर निर्भर न हों। उदाहरण के लिए, कई स्वतंत्र अनुभागों में प्रोफ़ाइल डेटा लोड करना: यदि अनुशंसा अनुभाग विफल होता है, तो प्रोफ़ाइल शीर्षक और मित्र सूची प्रदर्शित होनी चाहिए।

CoroutineScope के साथ काम करते समय सामान्य गलतियाँ

Kotlin में CoroutineScope का उपयोग करते समय डेवलपर्स की सबसे सामान्य गलतियों पर नज़र डालते हैं।

गलती 1: Scope रद्द करना भूलना

कोरूटीन लीक का सबसे सामान्य परिदृश्य कंपोनेंट समाप्त होने पर cancel कॉल किए बिना scope बनाना है। यदि scope रद्द नहीं किया गया, तो कोरूटीन चलते रहते हैं, ऑब्जेक्ट्स के संदर्भ रखते हैं। Android में, viewModelScope या lifecycleScope का उपयोग करें, जो स्वचालित रूप से रद्द हो जाते हैं।

गलती 2: Activity या Fragment में GlobalScope का उपयोग

GlobalScope Android कंपोनेंट जीवनचक्र को अनदेखा करता है। Activity बंद होने के बाद GlobalScope में चलाया गया कोरूटीन निष्पादित होता रहेगा और UI अपडेट करने का प्रयास करेगा — जिससे क्रैश होगा। UI कंपोनेंट के लिए हमेशा lifecycleScope का उपयोग करें।

गलती 3: रद्द किए गए scope का पुन: उपयोग

cancel() कॉल करने के बाद, scope का पुन: उपयोग नहीं किया जा सकता — उसके अंदर के सभी कोरूटीन पहले ही पूरे हो चुके हैं। फ़ैक्टरी फ़ंक्शन के माध्यम से नया CoroutineScope इंस्टेंस बनाएँ। Job() पुन: सक्रियण का समर्थन नहीं करता।

गलती 4: CoroutineScope इंटरफ़ेस का गलत डेलिगेशन

by के साथ डेलिगेट करने पर, क्लास को सार्वजनिक cancel() विधि मिलती है जिसे कहीं से भी कॉल किया जा सकता है, जिससे एनकैप्सुलेशन टूटता है। इंटरफ़ेस डेलिगेट करने के बजाय scope को प्राइवेट फ़ील्ड के रूप में संग्रहीत करें।

अक्सर पूछे जाने वाले प्रश्न

CoroutineScope, CoroutineContext से कैसे अलग है?

CoroutineScope एक इंटरफ़ेस है जो CoroutineContext का मालिक है और कोरूटीन जीवनचक्र के लिए जिम्मेदार है। CoroutineContext तत्वों (डिस्पैचर, job, त्रुटि हैंडलर) का एक सेट है जो परिभाषित करता है कि कोरूटीन “कैसे” निष्पादित होता है। एक अंतर: scope कोरूटीन बनाता है, जबकि संदर्भ उनके व्यवहार को नियंत्रित करता है।

क्या SupervisorJob के साथ CoroutineScope बनाया जा सकता है?

हाँ, यह एक मानक पैटर्न है: CoroutineScope(Dispatchers.IO + SupervisorJob()). SupervisorJob किसी एक चाइल्ड कोरूटीन में अपवाद होने पर बाकी कोरूटीन के कैस्केडिंग रद्दीकरण को रोकता है। यह स्वतंत्र समानांतर कार्यों के लिए उपयोगी है जहाँ एक में त्रुटि दूसरे को नहीं रोकनी चाहिए।

CoroutineScope में कितने कोरूटीन हो सकते हैं?

scope में कोरूटीन की कोई सीमा नहीं है — वे केवल उपलब्ध मेमोरी और डिस्पैचर सेटिंग्स द्वारा सीमित हैं। व्यावहारिक सीमा आमतौर पर एक scope में हजारों सक्रिय कोरूटीन होती है। हालाँकि, बड़ी संख्या में कोरूटीन आर्किटेक्चरल समस्याओं का संकेत हो सकती है।

CoroutineScope वाले कोड का परीक्षण कैसे करें?

सही तरीका है कंस्ट्रक्टर के माध्यम से क्लास में scope पास करना या kotlinx-coroutines-test से runBlockingTest / runTest का उपयोग करना। परीक्षणों में, आप scope को TestCoroutineDispatcher से बदल सकते हैं और कोरूटीन निष्पादन को मैन्युअल रूप से नियंत्रित कर सकते हैं।

क्या एक कोरूटीन का अपना scope हो सकता है?

नहीं, scope कोरूटीन के लिए एक बाहरी कंटेनर है। कोरूटीन स्वयं scope नहीं है। हालाँकि, कोरूटीन के अंदर आप coroutineScope या supervisorScope के माध्यम से चाइल्ड कोरूटीन को समानांतर चलाने के लिए नया scope बना सकते हैं।

सारांश

  • CoroutineScope — coroutineContext फ़ील्ड वाला इंटरफ़ेस, जो उसके अंदर चलाए गए कोरूटीन का जीवनचक्र परिभाषित करता है
  • संरचनात्मक समवर्तीता — scope रद्द करने से सभी चाइल्ड कोरूटीन स्वचालित रूप से रद्द होते हैं, मेमोरी लीक रुकती है
  • Job और SupervisorJob — त्रुटि प्रबंधन के दो तरीके: कैस्केडिंग रद्दीकरण (Job) और पृथक त्रुटियाँ (SupervisorJob)
  • GlobalScope — जीवनचक्र बंधन के अभाव के कारण प्रोडक्शन के लिए अनुशंसित नहीं
  • coroutineScope बनाम supervisorScope — परमाणु समानांतर संचालन बनाम स्वतंत्र समानांतर कार्य
  • viewModelScope और lifecycleScope — Android के लिए तैयार scopes, कंपोनेंट समाप्त होने पर स्वचालित रूप से रद्द
  • फ़ैक्टरी फ़ंक्शन — CoroutineContext + स्पष्ट cancel कॉल के माध्यम से scope बनाने का पसंदीदा तरीका

हम एक मोबाइल एप्लिकेशन टर्नकी विकसित करेंगे

IT Sectr 2017 से स्टार्टअप और व्यवसायों के लिए iOS और Android एप्लिकेशन बनाता है। हम आपको सलाह देंगे और सर्वोत्तम समाधान प्रस्तावित करेंगे।

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

यह भी पढ़ें