runBlocking — Kotlin میں ایک Coroutine Builder جو دیے گئے کوروٹین کے مکمل ہونے تک موجودہ تھریڈ کو بلاک کرتا ہے۔ launch اور async کے برعکس، یہ suspend فنکشن نہیں ہے اور عام (بلاک کرنے والے) کوڈ سے بلایا جا سکتا ہے۔ JetBrains دستاویزات، 2024 کے مطابق، runBlocking ہم وقت اور غیر ہم وقت دنیاؤں کے درمیان ایک پل کا کام کرتا ہے، جس سے main فنکشن اور ٹیسٹوں سے کوروٹین شروع کی جا سکتی ہیں۔
اہم نکات
runBlocking ایک Kotlin فنکشن ہے جو ایک نیا CoroutineScope بناتا ہے اور دیے گئے کوروٹین کو چلاتا ہے، موجودہ تھریڈ کو اس کے مکمل ہونے تک بلاک کرتا ہے۔ دیگر تمام Coroutine Builder کے برعکس، runBlocking کوئی suspend فنکشن نہیں ہے اور عام ہم وقت کوڈ سے بلایا جا سکتا ہے۔ runBlocking کا دستخط CoroutineContext اور ایک suspend بلاک لیتا ہے، T قسم کا نتیجہ لوٹاتا ہے۔
public fun <T> runBlocking(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> T
): T
runBlocking موجودہ تھریڈ پر ایک نیا event-loop شروع کرتا ہے۔ جب کوروٹین کسی suspend فنکشن (مثلاً delay() یا await()) کو کال کرتا ہے، runBlocking تھریڈ کو بلاک کرتا ہے اور معطل شدہ کوروٹین کے دوبارہ شروع ہونے تک اسی تھریڈ پر دیگر طے شدہ کوروٹین چلاتا ہے۔ یہ تعاونی بلاکنگ ہے — تھریڈ بیکار نہیں رہتا بلکہ دیگر کوروٹین پر کارروائی کرتا ہے۔
runBlocking کا داخلی طریقہ کار event-loop پر مبنی ہے: جب کوئی suspend فنکشن بلایا جاتا ہے، runBlocking موجودہ بلاک کی عملدرآمد کو روکتا ہے اور قطار سے دیگر کوروٹین چلاتا ہے۔ جب suspend فنکشن مکمل ہوتا ہے، عملدرآمد دوبارہ شروع ہوتا ہے۔ یہ چکر اس وقت تک جاری رہتا ہے جب تک تمام کوروٹین ختم نہ ہو جائیں۔
runBlocking کوروٹین چلانے کے لیے اپنا سنگل تھریڈ پول استعمال کرتا ہے۔ Dispatchers.IO یا Default کے برعکس، runBlocking تھریڈ تبدیل نہیں کرتا — یہ تمام کوروٹین کو موجودہ تھریڈ پر پروسیس کرتا ہے، ان کی عملدرآمد کو ایک دوسرے میں گوندھتا ہے۔ یہ واحد بلڈر ہے جو اسی تھریڈ پر عملدرآمد کی ضمانت دیتا ہے۔
fun main() {
val threadName = Thread.currentThread().getName()
println("runBlocking سے پہلے $threadName پر")
val result = runBlocking {
println("runBlocking کے اندر ${Thread.currentThread().getName()} پر")
delay(500L)
"Done"
}
println("runBlocking کے بعد: $result")
}
آؤٹ پٹ ظاہر کرے گا کہ تینوں println بیانات اسی تھریڈ پر عملدرآمد ہوتے ہیں۔ runBlocking تھریڈ تبدیل نہیں کرتا بلکہ event-loop کا استعمال کرتے ہوئے ایک تھریڈ کے اندر تعاونی ملٹی ٹاسکنگ منظم کرتا ہے۔
runBlocking تین منظرناموں میں جائز ہے: کنسول ایپلیکیشنز میں main() داخلے کا نقطہ، suspend فنکشنز کے یونٹ ٹیسٹ، اور پل — کال بیک پر مبنی یا بلاک کرنے والی لائبریریوں سے suspend کوڈ کال کرنا۔ پروڈکشن Android کوڈ میں، مین تھریڈ پر استعمال سختی سے ممنوع ہے۔
| منظرنامہ | اطلاقی صلاحیت | خطرات |
|---|---|---|
| main() کنسول ایپلیکیشن کا | ہاں | کوئی نہیں — یہ داخلے کا نقطہ ہے، تھریڈ UI کو بلاک نہیں کرتا |
| JUnit ٹیسٹ | ہاں | کم سے کم — ٹیسٹ تعریف کے مطابق ہم وقت ہوتے ہیں |
| Android UI تھریڈ | نہیں | ANR، تاخیر، انٹرفیس جمنا |
| Callback → کوروٹین | ہاں، احتیاط سے | لمبی کارروائیوں میں تھریڈ پول بلاک ہونا |
Android ٹیسٹوں کے لیے، runBlocking کی بجائے kotlinx-coroutines-test کے TestDispatcher کا استعمال کریں۔ یہ وقت کنٹرول، خودکار صفائی اور ٹیسٹ علیحدگی فراہم کرتا ہے۔
زیادہ تر منظرناموں میں، runBlocking کو غیر ہم وقت متبادل سے تبدیل کیا جا سکتا ہے اور کیا جانا چاہیے۔ Android کے لیے، یہ viewModelScope، lifecycleScope یا مناسب ڈسپیچر کے ساتھ CoroutineScope ہیں۔ ٹیسٹوں کے لیے — TestCoroutineDispatcher اور runTest۔
// برا: Android مین تھریڈ پر runBlocking
runBlocking(Dispatchers.Main) {
val result = networkApi.fetchData()
textView.setText(result)
}
// اچھا: lifecycleScope
lifecycleScope.launch {
val result = withContext(Dispatchers.IO) { networkApi.fetchData() }
textView.setText(result)
}
ٹیسٹوں کے لیے، متبادل kotlinx-coroutines-test لائبریری کا runTest ہے۔ یہ مجازی وقت کے ساتھ TestCoroutineScope بناتا ہے، حقیقی انتظار کے بغیر تاخیر کی جانچ کی اجازت دیتا ہے۔ یہ ٹیسٹوں کو تیز اور تعییناتی بناتا ہے۔
سب سے عام منظرنامہ suspend فنکشنز کی جانچ ہے۔ ٹیسٹوں میں runBlocking فن تعمیر کو تبدیل کیے بغیر کوروٹین کے نتیجے کا ہم وقت انتظار کرنے کی اجازت دیتا ہے۔ دوسرا منظرنامہ کال بیک API والی لائبریریاں ہیں، جہاں suspend فنکشنز runBlocking کے ذریعے بلاک کرنے والے سیاق و سباق سے بلائے جاتے ہیں۔
// runBlocking کے ساتھ suspend فنکشن ٹیسٹ کریں
class RepositoryTest {
@Test
fun `fetchUser returns correct data`() {
val repository = UserRepository(FakeApi())
val result = runBlocking {
repository.fetchUser("123")
}
assertEquals("John", result.name)
assertEquals("john@test.com", result.email)
}
}
کال بیک اور suspend دنیاؤں کے درمیان پل کے لیے، callbacks کی بجائے runBlocking کے ساتھ CompletableDeferred استعمال کریں — یہ غیر ہم وقت کارروائی کے سلسلے کو آسان بناتا ہے اور کوڈ پڑھنے کی اہلیت کو بہتر بناتا ہے۔
runBlocking کا غلط استعمال بلاک کرنے والے طریقہ کار سے کوروٹین میں منتقلی کے وقت عام غلطیوں میں سے ایک ہے۔ اہم مسائل: Android مین تھریڈ پر کال، runBlocking کو ایک دوسرے میں گھسنا، غیر ہم وقت فنکشنز کے اندر استعمال، اور runBlocking کے ذریعے لمبی کارروائیاں شروع کرنا۔
سنہری اصول: runBlocking ایک پل ہے، متبادل نہیں۔ اسے صرف بلاک کرنے والی اور نان بلاک کرنے والی دنیاؤں کو جوڑنے کے لیے استعمال کریں۔ دیگر تمام کاموں کے لیے، launch، async یا lifecycleScope استعمال کریں۔
اکثر پوچھے گئے سوالات
runBlocking واحد بلڈر ہے جو suspend فنکشن نہیں ہے۔ یہ موجودہ تھریڈ پر event-loop شروع کرتا ہے اور جب تک تمام کوروٹین مکمل نہیں ہو جاتے کنٹرول واپس نہیں کرتا۔ launch اور async فوری طور پر کنٹرول واپس کرتے ہیں، کوروٹین کو پس منظر میں چلاتے ہیں۔
سفارش نہیں کی جاتی۔ ViewModel میں ایک بلٹ ان viewModelScope ہے جو خود بخود کوروٹین کا انتظام کرتا ہے اور تباہی پر انہیں منسوخ کرتا ہے۔ ViewModel میں runBlocking تھریڈ کو بلاک کرتا ہے اور لائف سائیکل منسوخی کا جواب نہیں دیتا۔
kotlinx-coroutines-test لائبریری سے runTest استعمال کریں۔ یہ مجازی وقت کنٹرول، خودکار منسوخی اور تعییناتی عملدرآمد کے ساتھ TestCoroutineScope فراہم کرتا ہے۔
Event-loop runBlocking کے اندر ایک واقعہ پروسیسنگ سائیکل ہے۔ جب کوئی کوروٹین معطل ہوتا ہے (مثلاً delay())، event-loop اسی تھریڈ پر دیگر تیار کوروٹین چلانے پر سوئچ کرتا ہے۔ یہ تھریڈ سوئچنگ کے بغیر ملٹی ٹاسکنگ کا وہم پیدا کرتا ہے۔
اسی تھریڈ پر گھسا ہوا runBlocking ایک ڈیڈ لاک بناتا ہے — بیرونی بلاک اندرونی کا انتظار کرتا ہے، لیکن اندرونی اس وقت تک شروع نہیں ہو سکتا جب تک بیرونی ختم نہ ہو۔ مختلف تھریڈز پر اس کی اجازت ہے لیکن ڈیبگنگ پیچیدگی کی وجہ سے سختی سے حوصلہ شکنی کی جاتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں