Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用kotlin协程并行运行两个作业,但等待另一个作业完成_Kotlin_Parallel Processing_Coroutine - Fatal编程技术网

如何使用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协同程

我的工作如下:

  • 异步膨胀复杂日历视图
  • 下载事件A
  • 下载活动B
  • 将日历视图添加到其父视图
  • 将事件添加到日历中
  • 将B事件添加到日历中
  • 我想要

    • 1、2、3必须异步启动
    • 4必须等待1
    • 5必须等待2和4
    • 6必须等待3和4
    • 6和5不应该相互依赖,可以在不同的时间运行
    • 4仅依赖于1,因此它可以在2或3完成之前运行
    我尝试了async Wait,但它使它们同时完成(如预期的那样)。我认为这个例子可能是学习并行编程概念的好方法,比如信号量互斥或旋转锁。但这太复杂了,我无法理解


    我应该如何使用Kotlin协同程序实现这些功能?

    这非常简单。您需要做的只是:

  • 实施
    CoroutineScope
    并创建
    CoroutineContext
    ,或使用
    GlobalScope
  • 使用本地
    CoroutineScope
    GlobalScope.launch()
    启动coroutine
  • 在协同程序中,使用
    async/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() }
    }