Kotlin Coroutine 初探(二)

本文介绍了Kotlin中Coroutine的基本用法,包括协程切换、异步执行、超时限制及协程流等内容,并通过示例代码展示了不同场景下的具体应用。

Kotlin Coroutine 初探(二)

针对Coroutine的一些常用方法进行说明。

切换协程

使用withContext来进行协程的切换。

    fun testChangeContext() {
        launch {
            Log.e("ViewModel", "launch--start:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")

            withContext(Dispatchers.IO) {
                delay(1000)
                Log.e("ViewModel", "withContext--IO:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")
            }

            withContext(mChangeCoroutineContext) {
                delay(1000)
                Log.e("ViewModel", "withContext--self:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")
            }

            mChangeCoroutineContext.close()
            Log.e("ViewModel", "launch--after:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")
        }
    }

输出:
change_dispatcher

注意:协程的切换,还和构建时指定的模式相关。

异步执行

使用async+await,来进行异步任务。

    fun testAsync() {
        launch {
            Log.e("ViewModel", "launch--start:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")

            withContext(Dispatchers.IO) {
                delay(1000)
                Log.e("ViewModel", "withContext--IO:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")
            }

            val deferred = async {
                delay(3000)
                Log.e("ViewModel", "launch--async:${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")
                "async"
            }

            Log.e("ViewModel", "launch--after:${deferred.await()};${Thread.currentThread().name};${Thread.currentThread().id};${coroutineContext[Job]}")
        }
    }

输出:
coroutine_async

超时限制

使用withTimeout来限制任务的执行时间。

    var acquired = 0

    inner class Resource {
        init {
            acquired++
        } // Acquire the resource

        fun close() {
            acquired--
        } // Release the resource
    }

    fun testConcurrence() {
        runBlocking {
//            repeat(10) { // Launch 100K coroutines
                launch(Dispatchers.IO) {
                    Log.e("ViewModel", "launch:$acquired;${Thread.currentThread().id}")
                    val resource = withTimeout(200) { // Timeout of 200 ms
                        Log.e("ViewModel", "withTimeout:$acquired;${Thread.currentThread().id}")
                        delay(500) // Delay for 500 ms
                        val r = Resource() // Acquire a resource and return it from withTimeout block
                        Log.e("ViewModel","withTimeout--delay:$acquired;${Thread.currentThread().id}")
                        r
                    }
                    resource.close() // Release the resource
                    Log.e("ViewModel", "launch--close:$acquired;${Thread.currentThread().id}")
                }
//            }
            Log.e("ViewModel", "runBlocking:$acquired;${Thread.currentThread().id}")
        }
        // Outside of runBlocking all coroutines have completed
        Log.e("ViewModel", "acquired:$acquired") // Print the number of resources still acquired
    }

输出:
coroutine_timeout

协程流

目前包含flowchannelFlow

    fun testFlow() = launch {
        try {
            val flowCost = measureTimeMillis {
                flow<Int> {
                    Log.e("ViewModel", "flow")
                    for (i in 1..5) {
                        delay(1000)
                        emit(i)
                    }
                }.collect {
                    Thread.sleep(1000)
//                delay(1000)
                    Log.e("ViewModel", "flow:$it")
                }
            }
            Log.e("ViewModel", "flow--cost:$flowCost")

            delay(10000)
            Log.e("ViewModel", "flow--done")
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

输出:
coroutine_flow

    fun testChannel() {
        launch {
            try {
                val channelCost = measureTimeMillis {
                    channelFlow<Int> {
                        Log.e("ViewModel", "channelFlow")
                        for (i in 1..5) {
                            delay(1000)
                            send(i)
                        }

                    }.collect {
//                        delay(100)
                        Thread.sleep(1000)
                        Log.e("ViewModel", "channelFlow:$it")
                    }
                }
                Log.e("ViewModel", "channelFlow--cost:$channelCost")

                delay(10000)//防止parentScope已经完成
                Log.e("ViewModel", "channelFlow--done")
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }

输出:
coroutine_channel

区别:在默认的构建和接收模式下:flow 是 Cold Stream,在没有切换线程的情况下,生产者和消费者是同步非阻塞的;channel 是 Hot Stream,实现了生产者和消费者异步非阻塞模型。

源码地址: https://pan.quark.cn/s/3916362e5d0a 在C#编程平台下,构建一个曲线编辑器是一项融合了图形用户界面(GUI)构建、数据管理及数学运算的应用开发任务。 接下来将系统性地介绍这个曲线编辑器开发过程中的核心知识点:1. **定制曲线面板展示数据曲线**: - 控件选用:在C#的Windows Forms或WPF框架中,有多种控件可用于曲线呈现,例如PictureBox或用户自定义的UserControl。 通过处理重绘事件,借助Graphics对象执行绘图动作,如运用DrawCurve方法。 - 数据图形化:通过线性或贝塞尔曲线连接数据点,以呈现数据演变态势。 这要求掌握直线与曲线的数学描述,例如两点间的直线公式、三次贝塞尔曲线等。 - 坐标系统与缩放比例:构建X轴和Y轴,设定坐标标记,并开发缩放功能,使用户可察看不同区间内的数据。 2. **在时间轴上配置多个关键帧数据**: - 时间轴构建:开发一个时间轴组件,显示时间单位刻度,并允许用户在特定时间点设置关键帧。 时间可表现为连续形式或离散形式,关键帧对应于时间轴上的标识。 - 关键帧维护:利用数据结构(例如List或Dictionary)保存关键帧,涵盖时间戳和关联值。 需考虑关键帧的添加、移除及调整位置功能。 3. **调整关键帧数据,通过插值方法获得曲线**: - 插值方法:依据关键帧信息,选用插值方法(如线性插值、样条插值,特别是Catmull-Rom样条)生成平滑曲线。 这涉及数学运算,确保曲线在关键帧之间无缝衔接。 - 即时反馈:在编辑关键帧时,即时刷新曲线显示,优化用户体验。 4. **曲线数据的输出**: - 文件类型:挑选适宜的文件格式存储数据,例如XML、JSON或...
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值