ইন kotlinx.coroutines
গ্রন্থাগার আপনি হয় ব্যবহার করে নতুন coroutine শুরু করতে পারেন launch
(এর সাথে join
) অথবা async
(সঙ্গে await
)। তাদের মধ্যে পার্থক্য কী?
ইন kotlinx.coroutines
গ্রন্থাগার আপনি হয় ব্যবহার করে নতুন coroutine শুরু করতে পারেন launch
(এর সাথে join
) অথবা async
(সঙ্গে await
)। তাদের মধ্যে পার্থক্য কী?
উত্তর:
launch
আগুন লাগাতে এবং কর্টিন ভুলে ব্যবহৃত হয় । এটি একটি নতুন থ্রেড শুরু করার মতো। যদি অভ্যন্তরের কোডটি launch
ব্যতিক্রম সহ সমাপ্ত হয়, তবে এটি কোনও থ্রেডে অপ্রকাশিত ব্যতিক্রমের মতো আচরণ করা হয় - সাধারণত ব্যাকএন্ড জেভিএম অ্যাপ্লিকেশনগুলিতে স্ট্যাডারে মুদ্রিত হয় এবং অ্যান্ড্রয়েড অ্যাপ্লিকেশন ক্র্যাশ করে। join
চালু কর্টিন সমাপ্তির জন্য অপেক্ষা করতে ব্যবহৃত হয় এবং এটি তার ব্যতিক্রম প্রচার করে না। যাইহোক, একটি ক্র্যাশ হওয়া শিশু কর্টিন তার পিতামাতার সাথে সম্পর্কিত ব্যতিক্রমটিও বাতিল করে।
async
এমন কোনও করোটিন শুরু করতে ব্যবহৃত হয় যা কিছু ফলাফলের গণনা করে । ফলাফল একটি দৃষ্টান্ত দ্বারা প্রতিনিধিত্ব করা হয় Deferred
এবং আপনি আবশ্যক ব্যবহার await
এটিতে। async
কোডের অভ্যন্তরে একটি অপ্রকাশিত ব্যতিক্রম ফলাফলের মধ্যে সংরক্ষণ করা হয় Deferred
এবং অন্য কোথাও বিতরণ করা হয় না, এটি প্রক্রিয়া না করা হলে নিঃশব্দে নামবে। আপনি async দিয়ে যে কর্টিনটি শুরু করেছেন তা ভুলে যাবেন না ।
আমি এই গাইডটি https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md উপকারী হতে পাই । আমি প্রয়োজনীয় অংশগুলি উদ্ধৃত করব
🦄 coroutine
মূলত, কর্টিনগুলি হালকা ওজনের থ্রেড।
সুতরাং আপনি কাউরটিনকে এমন কিছু হিসাবে ভাবতে পারেন যা খুব কার্যকরীভাবে থ্রেড পরিচালনা করে।
🐤 আরম্ভ
fun main(args: Array<String>) {
launch { // launch new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}
সুতরাং launch
একটি পটভূমি থ্রেড শুরু হয়, কিছু করে এবং তত্ক্ষণাত্ একটি টোকন প্রদান করে Job
। আপনি কল করতে পারেন join
এই Job
পর্যন্ত এই অবরোধ করার launch
থ্রেড সম্পন্ন হয়ে
fun main(args: Array<String>) = runBlocking<Unit> {
val job = launch { // launch new coroutine and keep a reference to its Job
delay(1000L)
println("World!")
}
println("Hello,")
job.join() // wait until child coroutine completes
}
🦆 ASYNC
ধারণামূলকভাবে, অ্যাসিঙ্ক ঠিক লঞ্চের মতো। এটি একটি পৃথক করোটিন শুরু করে যা একটি হালকা ওজনের থ্রেড যা অন্যান্য সমস্ত কর্টিনগুলির সাথে একযোগে কাজ করে। পার্থক্যটি হ'ল লঞ্চটি কোনও চাকরি দেয় এবং কোনও ফলস্বরূপ মান বহন করে না, যখন অ্যাসিঙ্ক একটি মুলতুবি ফেরত দেয় - একটি হালকা ওজনহীন-ব্লকিং ভবিষ্যত যা পরে কোনও ফলাফল দেওয়ার প্রতিশ্রুতি উপস্থাপন করে।
সুতরাং async
একটি পটভূমি থ্রেড শুরু হয়, কিছু করে এবং তত্ক্ষণাত্ একটি টোকন প্রদান করে Deferred
।
fun main(args: Array<String>) = runBlocking<Unit> {
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
}
এর শেষ পরিণতি পেতে আপনি .awit () একটি স্থগিত মানটিতে ব্যবহার করতে পারেন তবে ডিফার্ডও একটি কাজ, সুতরাং প্রয়োজনে আপনি এটি বাতিল করতে পারেন।
সুতরাং Deferred
আসলে একটি Job
। Https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html দেখুন
interface Deferred<out T> : Job (source)
Y async ডিফল্টরূপে আগ্রহী
CoroutineStart.LAZY এর মান সহ alচ্ছিক প্রারম্ভিক প্যারামিটারটি ব্যবহার করে অ্যাসিঙ্ক করার জন্য একটি অলস বিকল্প রয়েছে। এটি কেবলমাত্র তখনই শুরু হয় যখন এর ফলাফলটির জন্য কিছু প্রতীক্ষিত প্রয়োজন হয় বা কোনও শুরুর কাজটি শুরু করা হয়।
launch
এবং async
নতুন কর্টিনগুলি শুরু করতে ব্যবহৃত হয়। কিন্তু, তারা তাদের বিভিন্নভাবে কার্যকর করে।
আমি খুব মৌলিক উদাহরণ দেখাতে চাই যা আপনাকে খুব সহজেই পার্থক্য বুঝতে সাহায্য করবে
- শুরু করা
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
btnCount.setOnClickListener {
pgBar.visibility = View.VISIBLE
CoroutineScope(Dispatchers.Main).launch {
val currentMillis = System.currentTimeMillis()
val retVal1 = downloadTask1()
val retVal2 = downloadTask2()
val retVal3 = downloadTask3()
Toast.makeText(applicationContext, "All tasks downloaded! ${retVal1}, ${retVal2}, ${retVal3} in ${(System.currentTimeMillis() - currentMillis)/1000} seconds", Toast.LENGTH_LONG).show();
pgBar.visibility = View.GONE
}
}
// Task 1 will take 5 seconds to complete download
private suspend fun downloadTask1() : String {
kotlinx.coroutines.delay(5000);
return "Complete";
}
// Task 1 will take 8 seconds to complete download
private suspend fun downloadTask2() : Int {
kotlinx.coroutines.delay(8000);
return 100;
}
// Task 1 will take 5 seconds to complete download
private suspend fun downloadTask3() : Float {
kotlinx.coroutines.delay(5000);
return 4.0f;
}
}
এই উদাহরণে, আমার কোড btnCount
বোতামের ক্লিকে 3 ডেটা ডাউনলোড করছে এবং pgBar
সমস্ত ডাউনলোড শেষ না হওয়া পর্যন্ত অগ্রগতি বার দেখায় । সেখানে 3 suspend
ফাংশন downloadTask1()
, downloadTask2()
এবং downloadTask3()
যা ডাউনলোডসমূহ তথ্য। এটি অনুকরণ করার জন্য, আমি delay()
এই ফাংশনগুলিতে ব্যবহার করেছি । এই ফাংশন জন্য অপেক্ষা 5 seconds
, 8 seconds
এবং 5 seconds
যথাক্রমে।
যেহেতু আমরা launch
এই সাসপেন্ড ফাংশনগুলি শুরু করার জন্য ব্যবহার করেছি , launch
সেগুলি ক্রমিকভাবে কার্যকর করা হবে (একের পর এক) । এর অর্থ এই যে, downloadTask2()
পরে শুরু করবেন downloadTask1()
সম্পন্ন পরার এবং downloadTask3()
পরে শুরু করবেন downloadTask2()
সম্পন্ন হয়।
আউটপুট স্ক্রিনশট হিসাবে Toast
, সমস্ত 3 ডাউনলোড সম্পূর্ণ করার জন্য নির্বাহের মোট সময়টি 5 সেকেন্ড + 8 সেকেন্ড + 5 সেকেন্ড = 18 সেকেন্ড সহ নেতৃত্ব দেয়launch
- ASYNC
আমরা দেখেছি হিসাবে যে launch
মৃত্যুদন্ড তোলে sequentially
3 কর্ম জন্য। সব কাজ শেষ করার সময় ছিল 18 seconds
।
যদি সেই কাজগুলি স্বতন্ত্র থাকে এবং যদি তাদের অন্যান্য টাস্কের গণনার ফলাফলের প্রয়োজন না হয় তবে আমরা সেগুলি চালাতে পারি concurrently
। এগুলি একই সাথে শুরু হয়ে পটভূমিতে একযোগে চলত। এটি দিয়ে করা যেতে পারে async
।
async
Deffered<T>
প্রকারের উদাহরণ প্রদান করে , যেখানে T
আমাদের সাসপেন্ড ফাংশনটি উপাত্তের ধরণ দেয়। উদাহরণ স্বরূপ,
downloadTask1()
ফিরে আসবে Deferred<String>
স্ট্রিং হিসাবে ফাংশন রিটার্ন টাইপ হয়downloadTask2()
ফিরে আসবে Deferred<Int>
int হিসাবে ফাংশন রিটার্ন টাইপ হয়downloadTask3()
ফিরে আসবে Deferred<Float>
float হিসাবে ফাংশন রিটার্ন টাইপ হয়রিটার্ন অবজেক্টটি async
টাইপ থেকে রিটার্নের Deferred<T>
মানটি টাইপ করতে আমরা ব্যবহার করতে পারি T
। await()
কল দিয়ে তা করা যায় । উদাহরণস্বরূপ কোডের নীচে চেক করুন
btnCount.setOnClickListener {
pgBar.visibility = View.VISIBLE
CoroutineScope(Dispatchers.Main).launch {
val currentMillis = System.currentTimeMillis()
val retVal1 = async(Dispatchers.IO) { downloadTask1() }
val retVal2 = async(Dispatchers.IO) { downloadTask2() }
val retVal3 = async(Dispatchers.IO) { downloadTask3() }
Toast.makeText(applicationContext, "All tasks downloaded! ${retVal1.await()}, ${retVal2.await()}, ${retVal3.await()} in ${(System.currentTimeMillis() - currentMillis)/1000} seconds", Toast.LENGTH_LONG).show();
pgBar.visibility = View.GONE
}
এইভাবে, আমরা একই সাথে সমস্ত 3 টি কার্য চালু করেছি। সুতরাং, সম্পূর্ণ করার জন্য আমার মোট সঞ্চালনের সময় শুধুমাত্র হবে 8 seconds
, যার জন্য সময় downloadTask2()
যেমন 3 কাজগুলো সব বৃহত্তম। আপনি নিম্নলিখিত স্ক্রিনশট এ এটি দেখতে পারেনToast message
launch
জন্য অনুক্রমিক funs, যখন async
জন্য সমবর্তী
launch
এবং async
নতুন কর্টিনগুলি শুরু করবে। আপনি কোনও বাচ্চাদের সাথে একটি একক কর্টিনের তুলনা করছেন 3 টি বাচ্চার সাথে একক কর্টিনের সাথে। আপনি প্রতিটি async
আমন্ত্রণের সাথে প্রতিস্থাপন করতে পারেন launch
এবং একমত হওয়ার সাথে একেবারেই কোনও পরিবর্তন হবে না।
উভয় কর্টিন বিল্ডার যথা লঞ্চ এবং অ্যাসিঙ্ক মূলত CoroutineScope প্রকারের রিসিভার সহ ল্যাম্বডাস যার অর্থ তাদের অভ্যন্তরীণ ব্লকটি একটি সাসপেন্ড ফাংশন হিসাবে সংকলিত, অতএব তারা উভয় একটি অ্যাসিনক্রোনাস মোডে চালিত হয় এবং তারা উভয়ই তাদের ব্লকটি ক্রমান্বয়ে কার্যকর করবে।
লঞ্চ এবং অ্যাসিঙ্কের মধ্যে পার্থক্য হ'ল তারা দুটি পৃথক সম্ভাবনা সক্ষম করে। লঞ্চ বিল্ডার একটি চাকরী ফেরত দেয় তবে অ্যাসিঙ্ক ফাংশনটি একটি ডিফার্ড অবজেক্ট ফিরিয়ে দেবে। আপনি কোনও ব্লক নির্বাহের জন্য লঞ্চটি ব্যবহার করতে পারেন যা আপনি এর থেকে কোনও প্রত্যাবর্তিত মান আশা করেন না যেমন একটি ডাটাবেসে লেখা বা কোনও ফাইল সংরক্ষণ করা বা কোনও কিছু প্রক্রিয়াজাতকরণ যা কেবলমাত্র এর পার্শ্ব প্রতিক্রিয়ার জন্য ডাকা হয়। অপরদিকে async যা পূর্ববর্তী হিসাবে আমি বলেছি একটি বিলম্বিত ফিরিয়ে দেয়, এটির ফলে আপনার ব্লকটি কার্যকর করা থেকে একটি কার্যকর মূল্য ফেরত দেয় যা এমন একটি বস্তু যা আপনার ডেটা আবৃত করে, সুতরাং আপনি এটি মূলত ফলাফলের জন্য ব্যবহার করতে পারেন তবে সম্ভবত এর পার্শ্ব প্রতিক্রিয়ার জন্যও। এনবি: আপনি পিছিয়ে ফ্রিটি করতে পারেন এবং অপেক্ষাটির ফাংশনটি ব্যবহার করে এর মান পেতে পারেন, যা কোনও মূল্য ফিরে না আসা বা ব্যতিক্রম না ছড়িয়ে দেওয়া পর্যন্ত আপনার বিবৃতি কার্যকর করতে অবরুদ্ধ করবে!
উভয় কর্টিন বিল্ডার (লঞ্চ এবং অ্যাসিঙ্ক) বাতিলযোগ্য।
আরও কিছু ?: লঞ্চের সাথে হাঁ, কোনও ব্যতিক্রম যদি তার ব্লকের মধ্যে ফেলে দেওয়া হয়, তবে কর্টিন স্বয়ংক্রিয়ভাবে বাতিল হয়ে যায় এবং ব্যতিক্রমগুলি সরবরাহ করা হয়। অন্যদিকে, যদি এটি অ্যাসিঙ্কের সাথে ঘটে তবে ব্যতিক্রমটি আরও প্রচারিত হয় না এবং প্রত্যাবর্তিত ডিফার্ড অবজেক্টের মধ্যে ধরা পড়ে / পরিচালনা করা উচিত।
coroutines উপর আরো https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html https://www.codementor.io/blog/kotlin-coroutines-6n53p8cbn1
প্রবর্তন একটি কাজ ফেরত
অ্যাসিঙ্ক একটি ফল দেয় (পিছিয়ে দেওয়া কাজ)
চাকরীটি শেষ না হওয়া পর্যন্ত অপেক্ষা করার জন্য জোড় সহ প্রবর্তন ব্যবহৃত হয় it ততক্ষণে বর্তমান থ্রেডটি অন্য কাজ (যেমন অন্য কোনও কর্টিন কার্যকর করার মতো) করার জন্য মুক্ত রেখে দেয় the
অ্যাসিঙ্ক কিছু ফলাফল গণনা করতে ব্যবহৃত হয়। এটি একটি কর্টিন তৈরি করে এবং তার ভবিষ্যত ফলাফল স্থগিতকরণ হিসাবে বাস্তবায়ন করে। ফলাফল স্থগিত বাতিল হলে চলমান করোটিন বাতিল হয়।
একটি অ্যাসিঙ্ক পদ্ধতি বিবেচনা করুন যা স্ট্রিংয়ের মান দেয়। যদি অ্যাসিঙ্ক পদ্ধতিটি অপেক্ষা না করে ব্যবহার করা হয় তবে এটি ডিফার্ড স্ট্রিংটি ফিরে আসবে তবে যদি অপেক্ষা করা হয় আপনি ফলাফল হিসাবে একটি স্ট্রিং পাবেন
অ্যাসিঙ্ক এবং লঞ্চের মধ্যে মূল পার্থক্য। আপনার Coroutine নির্বাহ শেষ করার পরে মুলতুবি টি টাইপ টির একটি নির্দিষ্ট মান প্রদান করে, যদিও কাজটি তা করে না।
অ্যাসিঙ্ক বনাম লঞ্চ অ্যাসিঙ্ক বনাম লঞ্চ ডিফ চিত্র
আরম্ভ / async কোন ফল
ফলাফল হিসাবে async