如何使用kotlin协程并行运行两个作业,但等待另一个作业完成
我的工作如下:如何使用kotlin协程并行运行两个作业,但等待另一个作业完成,kotlin,parallel-processing,coroutine,Kotlin,Parallel Processing,Coroutine,我的工作如下: 异步膨胀复杂日历视图 下载事件A 下载活动B 将日历视图添加到其父视图 将事件添加到日历中 将B事件添加到日历中 我想要 1、2、3必须异步启动 4必须等待1 5必须等待2和4 6必须等待3和4 6和5不应该相互依赖,可以在不同的时间运行 4仅依赖于1,因此它可以在2或3完成之前运行 我尝试了async Wait,但它使它们同时完成(如预期的那样)。我认为这个例子可能是学习并行编程概念的好方法,比如信号量互斥或旋转锁。但这太复杂了,我无法理解 我应该如何使用Kotlin协同程
- 1、2、3必须异步启动
- 4必须等待1
- 5必须等待2和4
- 6必须等待3和4
- 6和5不应该相互依赖,可以在不同的时间运行
- 4仅依赖于1,因此它可以在2或3完成之前运行
我应该如何使用Kotlin协同程序实现这些功能?这非常简单。您需要做的只是:
CoroutineScope
并创建CoroutineContext
,或使用GlobalScope
CoroutineScope
或GlobalScope.launch()
启动coroutineasync/await
运行/等待异步操作李>
您可以将下一个代码应用于您的算法(所有解释都在注释中):
class-SomeClass:CoroutineScope{
私有变量作业:作业=作业()
//创建本地协同文本
覆盖val coroutineContext:coroutineContext
get()=调度程序.Main+作业
//如果不再需要作业,请取消该作业
有趣的{
作业。取消()
}
有趣的工作{
//启动协同程序
发射{
//并行运行Job1、Job2、Job3,asyncIO-是CoroutineScope上的一个扩展函数
val d1=asyncIO{job1()}
val d2=asyncIO{job2()}
val d3=asyncIO{job3()}
//等待Job1的结果
val job1Result=d1.await()
//运行作业4
val d4=asyncIO{job4(job1Result)}
//正在等待作业2和作业4的结果
val job2Result=d2.await()
val job4Result=d4.await()
//运行作业5
val d5=asyncIO{job5(job2Result,job4Result)}
//等待Job3的结果
val job3Result=d3.await()
//运行作业6
val d6=asyncIO{job6(job3Result,job4Result)}
onDone(d5.await(),d6.await())
}
}
private fun onDone(job5Result:String,job6Result:String){
//根据作业5和作业6的结果做一些事情
}
乐趣作业1():字符串{
返回“作业1的结果”
}
乐趣作业2():字符串{
返回“作业2的结果”
}
乐趣作业3():字符串{
返回“作业3的结果”
}
乐趣作业4(作业1结果:字符串):字符串{
返回“job4的结果”
}
有趣的作业5(作业2Result:String,作业4Result:String):String{
返回“作业5的结果”
}
有趣的job6(job3Result:String,job4Result:String):String{
返回“作业6的结果”
}
//扩展函数
异步IO(ioFun:()->T)=异步(Dispatchers.IO){ioFun()}
}
这真的很容易。似乎我没有完全理解异步等待。现在我知道了,多亏了你。非常感谢hi@Sergey如何控制每个作业让我们假设我只想在所有作业执行时取消作业1,但不想干扰或妨碍其他作业的执行。hi@Min2,您可以尝试调用d1.cancel()
取消作业。如果它取消了父协同程序,考虑使用监督任务或监督范围。关于结构化并发的另一个有用链接:出于某种原因,当我执行此操作时,只有第一个作业运行,第二个作业从不运行。。我也没有返回值,但只想在GlobalScope.launch中运行两个作业,但第二个作业必须在第一个作业完成后进行。这导致第二个任务从未触发。有什么想法吗?另外,我使用async{},因为asyncIO不存在
class SomeClass : CoroutineScope {
private var job: Job = Job()
// creating local CoroutineContext
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
// cancel the Job if it is no longer needed
fun onClear() {
job.cancel()
}
fun doJob() {
// launch coroutine
launch {
// run Job1, Job2, Job3 in parallel, asyncIO - is an extension function on CoroutineScope
val d1 = asyncIO { job1() }
val d2 = asyncIO { job2() }
val d3 = asyncIO { job3() }
// waiting for result of Job1
val job1Result = d1.await()
// run Job4
val d4 = asyncIO { job4(job1Result) }
// waiting for result of Job2 and Job4
val job2Result = d2.await()
val job4Result = d4.await()
// run Job5
val d5 = asyncIO { job5(job2Result, job4Result) }
// waiting for result of Job3
val job3Result = d3.await()
// run Job6
val d6 = asyncIO { job6(job3Result, job4Result) }
onDone(d5.await(), d6.await())
}
}
private fun onDone(job5Result: String, job6Result: String) {
// do something with result of Job5 and Job6
}
fun job1(): String {
return "Result of job1"
}
fun job2(): String {
return "Result of job2"
}
fun job3(): String {
return "Result of job3"
}
fun job4(job1Result: String): String {
return "Result of job4"
}
fun job5(job2Result: String, job4Result: String): String {
return "Result of job5"
}
fun job6(job3Result: String, job4Result: String): String {
return "Result of job6"
}
// extension function
fun <T> CoroutineScope.asyncIO(ioFun: () -> T) = async(Dispatchers.IO) { ioFun() }
}