精华内容
下载资源
问答
  • 启动协程的函数
    2022-09-04 15:05:25

    启动协程的基本方式

    1.GlobalScope.launch

    代码示例:

    fun testGlobalScope() {
        GlobalScope.launch {
            println("Coroutinue started!")
            delay(1000L)
            println("Hello World!")
        }
        println("After launch!")
        Thread.sleep(2000L)
        println("Process end!")
    }
    
    
    /**
     * After launch!
     * Coroutinue started!
     * Hello World!
     * Process end!
     */
    @DelicateCoroutinesApi
    public object GlobalScope : CoroutineScope {
        /**
         * Returns [EmptyCoroutineContext].
         */
        override val coroutineContext: CoroutineContext
            get() = EmptyCoroutineContext
    }
    public fun CoroutineScope.launch(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> Unit
    ): Job {
        val newContext = newCoroutineContext(context)
        val coroutine = if (start.isLazy)
            LazyStandaloneCoroutine(newContext, block) else
            StandaloneCoroutine(newContext, active = true)
        coroutine.start(start, coroutine, block)
        return coroutine
    }

    launch函数是CoroutineScope的扩展函数,它有三个参数:

    1.  context: CoroutineContext = EmptyCoroutineContext, 第一个参数是协程上下文,它的默认值是 EmptyCoroutineContext,如果不传这个参数,默认就会使用 EmptyCoroutineContext。也可以传入 Kotlin 官方为我们提供的 Dispatchers,来指定协程运行的线程池。(Dispatchers.IO、Dispatchers.Unconfined、Dispatchers.Main)
    2. start: CoroutineStart = CoroutineStart.DEFAULT,第二个参数是协程的启动模式,默认值是CoroutineStart.DEFAULT,CoroutineStart 是一个枚举类,一共有:DEFAULT、LAZY、ATOMIC、UNDISPATCHED。
    3. block: suspend CoroutineScope.() -> Unit,第三个参数是函数类型block,它的类型是suspend CoroutineScope.() -> Unit。本质是一个挂起函数。
    4. 函数的返回值是一个 Job,它其实代表的是协程的句柄,并不能返回协程的执行结果。

    2.runBlocking 启动协程

    代码示例

    fun testRunBlocking2() {
        runBlocking {
            println("Coroutinue started!")
            delay(1000L)
            println("Hello World!")
        }
        println("After Launch")
        Thread.sleep(2000L)
        println("Process end")
    }
    
    
    
    /**
     * Coroutinue started!
     * Hello World!
     * After Launch
     * Process end
     */
    @Throws(InterruptedException::class)
    public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
        contract {
            callsInPlace(block, InvocationKind.EXACTLY_ONCE)
        }
        val currentThread = Thread.currentThread()
        val contextInterceptor = context[ContinuationInterceptor]
        val eventLoop: EventLoop?
        val newContext: CoroutineContext
        if (contextInterceptor == null) {
            // create or use private event loop if no dispatcher is specified
            eventLoop = ThreadLocalEventLoop.eventLoop
            newContext = GlobalScope.newCoroutineContext(context + eventLoop)
        } else {
            // See if context's interceptor is an event loop that we shall use (to support TestContext)
            // or take an existing thread-local event loop if present to avoid blocking it (but don't create one)
            eventLoop = (contextInterceptor as? EventLoop)?.takeIf { it.shouldBeProcessedFromContext() }
                ?: ThreadLocalEventLoop.currentOrNull()
            newContext = GlobalScope.newCoroutineContext(context)
        }
        val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop)
        coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
        return coroutine.joinBlocking()
    }

    runBlocking是普通函数,第一个参数:context: CoroutineContext,协程上下文。第二个参数是函数类型,block: suspend CoroutineScope.() -> T,函数类型是有返回值类型 T 的,与 runBlocking 的返回值类型是一样的,runBlocking 其实是可以从协程当中返回执行结果的。

    fun testRunBlocking() {
        val runBlockingResult = runBlocking {
            delay(500L)
            return@runBlocking "HaHa"
        }
        println("result:$runBlockingResult")
    }
    
    result:HaHa

    runBlocking特点:

    1. runBlocking 启动的协程会阻塞当前线程的执行。

    3.async 启动协程

    使用 async{} 创建协程,可以通过它返回的Deferred拿到协程的执行结果。

    代码示例

    fun testAsync() {
        runBlocking {
            val deferred = async {
                println("do async:${Thread.currentThread().name}")
                delay(1000L)
                return@async "do completed"
            }
            println("After async:${Thread.currentThread().name}")
            val result = deferred.await()
            println("Result is: $result")
        }
    }
    
    After async:main @coroutine#1
    do async:main @coroutine#2
    Result is: do completed
    public fun <T> CoroutineScope.async(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> T
    ): Deferred<T> {
        val newContext = newCoroutineContext(context)
        val coroutine = if (start.isLazy)
            LazyDeferredCoroutine(newContext, block) else
            DeferredCoroutine<T>(newContext, active = true)
        coroutine.start(start, coroutine, block)
        return coroutine
    }

    async注意点

    1.  async 启动协程以后,不会阻塞当前程序的执行流程。
    2.  async{}的返回值,是一个 Deferred 对象,它的 await() 方法,就可以拿到协程的执行结果。
    3. await只是等待执行完,并不是触发执行。

    更多相关内容
  • asyncio 执行非协程函数
    import asyncio
    import time
    from concurrent.futures.thread import ThreadPoolExecutor
    def commonmethod(value):
        print(value)
        time.sleep(2)
        print('done')
        return "it is ok"
    
    
    async def main(value):
         # 获取当前正在执行的事件循环
        loop = asyncio.get_running_loop()
        # 使用run_in_executor 执行非协程函数
    
        # 第一步是调用ThreadPoolExecutor的submit方法,去线程池中申请一个线程执行commonmethod方法,并返回一个concurrent.futures.Future对象
        # 第二步 调用asyncio.wrap_future将concurrent.futures.Future转换成asyncio.Feture
        # 第一个参数为None,默认使用线程池
        # result = loop.run_in_executor(None,commonmethod,value)
        # response = await result
        # print(response)
    
        # 显示的声明线程池
        with ThreadPoolExecutor(max_workers=10) as worker:
            result = loop.run_in_executor(worker,commonmethod,value)
            response = await result
            print(response)
    
    # 将协程对象添加到事件循环中,并运行
    tasks=[main(i) for i in range(5)]
    
    # 可以wait的对象包括:协程对象,task
    # asyncio.run会创建一个事件循环,并将携程对象加入到事件循环
    asyncio.run(asyncio.wait(tasks))
    

    future

    import asyncio
    
    async def test(fu):
        print(1)
        await asyncio.sleep(2)
        fu.set_result(666)
    
    async def main():
        # 获取当前正在执行的事件循环
        loop = asyncio.get_running_loop()
    
        fu = loop.create_future()
        # 创建task对象,加入到事件循环中
        task= asyncio.create_task(test(fu))
    
        await task
    
        # 等待返回值
        response = await fu
    
        print(response)
    
    asyncio.run(main())
    
    展开全文
  • 为了管理协程和I/O的回调函数,asyncio库的事件循环也能基于定时的方式调用普通的函数,使用call_soon()函数,例子如下:import asyncio import functools def callback(arg, *, kwarg='default'): print('...

    为了管理协程和I/O的回调函数,asyncio库的事件循环也能基于定时的方式调用普通的函数,使用call_soon()函数,例子如下:

    import asyncio
    import functools
    
    
    def callback(arg, *, kwarg='default'):
        print('callback invoked with {} and {}'.format(arg, kwarg))
    
    
    async def main(loop):
        print('registering callbacks')
        loop.call_soon(callback, 1)
        wrapped = functools.partial(callback, kwarg='not default')
        loop.call_soon(wrapped, 2)
    
        await asyncio.sleep(0.1)
    
    
    event_loop = asyncio.get_event_loop()
    try:
        print('entering event loop')
        event_loop.run_until_complete(main(event_loop))
    finally:
        print('closing event loop')
        event_loop.close()
    

    结果输出如下:

    entering event loop
    registering callbacks
    callback invoked with 1 and default
    callback invoked with 2 and not default
    closing event loop

    在这个例子里,当需要在回调函数里传送多个参数时,使用partial函数的功能。

    Python游戏开发入门

    你也能动手修改C编译器

    纸牌游戏开发

    http://edu.csdn.net/course/detail/5538 

    五子棋游戏开发

    http://edu.csdn.net/course/detail/5487
    RPG游戏从入门到精通
    http://edu.csdn.net/course/detail/5246
    WiX安装工具的使用
    http://edu.csdn.net/course/detail/5207
    俄罗斯方块游戏开发
    http://edu.csdn.net/course/detail/5110
    boost库入门基础
    http://edu.csdn.net/course/detail/5029
    Arduino入门基础
    http://edu.csdn.net/course/detail/4931
    Unity5.x游戏基础入门
    http://edu.csdn.net/course/detail/4810
    TensorFlow API攻略
    http://edu.csdn.net/course/detail/4495
    TensorFlow入门基本教程
    http://edu.csdn.net/course/detail/4369
    C++标准模板库从入门到精通 
    http://edu.csdn.net/course/detail/3324
    跟老菜鸟学C++
    http://edu.csdn.net/course/detail/2901
    跟老菜鸟学python
    http://edu.csdn.net/course/detail/2592
    在VC2015里学会使用tinyxml库
    http://edu.csdn.net/course/detail/2590
    在Windows下SVN的版本管理与实战 
    http://edu.csdn.net/course/detail/2579
    Visual Studio 2015开发C++程序的基本使用 
    http://edu.csdn.net/course/detail/2570
    在VC2015里使用protobuf协议
    http://edu.csdn.net/course/detail/2582
    在VC2015里学会使用MySQL数据库
    http://edu.csdn.net/course/detail/2672


    展开全文
  • Kotlin协程:启动协程

    2022-05-01 00:00:20
    Kotlin 启动协程有 3 种方式:launch、async 和 runBlocking。 在使用协程之前需要引入协程库依赖。 "org.jetbrains.kotlinx:kotlinx-coroutines-core:$versions.coroutines" 在运行示例前,配置协程调试 VM 参数:...

    Kotlin 启动协程有 3 种方式:launch、async 和 runBlocking。

    在使用协程之前需要引入协程库依赖。

    "org.jetbrains.kotlinx:kotlinx-coroutines-core:$versions.coroutines"
    

    在运行示例前,配置协程调试 VM 参数:
    Edit config -> VM options

    -Dkotlinx.coroutines.debug
    

    launch

    launch用来启动协程,但是不需要获取运行后的返回结果。它类似于”射箭“场景,将箭发射出去,但是不需要箭返回。使用者不关心协程的返回值。

    launch 使用方法

    使用 launch 时需要一个协程作用域,这里先使用 GlobalScope。

    fun main() {
        GlobalScope.launch {
            println("Coroutine started: ${Thread.currentThread().name}")
            delay(1000L)
            println("Hello World!")
        }
        
        println("After launch:${Thread.currentThread().name}")
        Thread.sleep(2000L)
    }
    

    输出结果

    After launch:main
    Coroutine started: DefaultDispatcher-worker-1 @coroutine#1
    Hello World!
    
    Process finished with exit code 0
    

    可以看出先执行 main 的代码,再执行 launch 中的代码。launch 中使用了 delay 方法延迟 1 秒,然后打印语句。主线程休眠 2 秒后程序运行结束。

    因为配置了 -Dkotlinx.coroutines.debug 参数,launch 打印线程名称时也打印了协程名称。

    Coroutine started: DefaultDispatcher-worker-1 @coroutine#1
    

    协程 coroutine#1 运行在 DefaultDispatcher-worker-1 线程。

    如果去掉最后一句 sleep,程序没有输出结果。

    fun main() {
        GlobalScope.launch {
            println("Coroutine started: ${Thread.currentThread().name}")
            delay(1000L)
            println("Hello World!")
        }
    
        println("After launch:${Thread.currentThread().name}")
    //    Thread.sleep(2000L)
    }
    

    输出结果

    After launch:main
    
    Process finished with exit code 0
    

    可以看出 launch 启动的协程没有运行。这是因为此时 launch 的方法执行在守护线程。守护线程的特点是如果所有非守护线程运行结束,守护线程会自动停止。在 main 线程运行结束后,launch 停止,里面的代码没有执行。

    如果我们将 launch 中的 delay 替换成 sleep,编译器会提示:Inappropriate blocking method call

    fun main() {
        GlobalScope.launch {
            println("Coroutine started: ${Thread.currentThread().name}")
            // Inappropriate blocking method call 
            Thread.sleep(1000L)
            println("Hello World!")
        }
    
        println("After launch:${Thread.currentThread().name}")
        Thread.sleep(2000L)
    }
    

    因为协程中应该运行非阻塞的函数,而 delay 就是一个非阻塞的挂起函数。挂起函数的特点就是”挂起-恢复“,是非阻塞的。

    delay 函数定义,具有 suspend 关键词。

    public suspend fun delay(timeMillis: Long) {
        if (timeMillis <= 0) return // don't delay
        return suspendCancellableCoroutine sc@ { cont: CancellableContinuation<Unit> ->
            cont.context.delay.scheduleResumeAfterDelay(timeMillis, cont)
        }
    }
    

    launch 介绍

    launch 方法的源码如下:

    public fun CoroutineScope.launch(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> Unit
    ): Job {
        val newContext = newCoroutineContext(context)
        val coroutine = if (start.isLazy)
        LazyStandaloneCoroutine(newContext, block) else
        StandaloneCoroutine(newContext, active = true)
        coroutine.start(start, coroutine, block)
        return coroutine
    }
    

    launch 是 CoroutineScope 的扩展方法,只能在 CoroutineScope 的内部运行。因此在使用时需要一个协程作用域。
    GlobalScope.launch 表示协程运行在全局作用域 GlobalScope。

    launch 方法有 3 个参数:context,start,block。分别是 CoroutineContext、CoroutineStart 和 suspend CoroutineScope.() -> Unit 类型。

    CoroutineContext 是协程上下文,通常用来指定协程的执行线程。

    CoroutineStart 是协程启动方式,默认是 DEFAULT 方式。DEFAULT 表示协程立即执行。还有一个 LAZY 方式,表示协程懒加载执行。

    suspend CoroutineScope.() -> Unit 表示协程需要执行的匿名函数类型。这个函数是挂起函数,用 suspend 关键字表示。它是 CoroutineScope 的扩展函数,用 CoroutineScope.() -> Unit 表示。() -> Unit 表示函数入参为空,返回值也为空。

    runBlocking

    runBlocking 也能用来启动协程,但是它是阻塞的。

    runBlocking 使用

    
    fun main() {
        runBlocking {                       // 1
            println("Coroutine started!")   // 2
            delay(1000L)                    // 3
            println("Hello World!")         // 4
        }
    
        println("After launch!")            // 5
        Thread.sleep(2000L)                 // 6
        println("Process end!")             // 7
    }
    

    输出结果:

    Coroutine started!
    Hello World!
    After launch!
    Process end!
    

    可以看出 runBlocking 是顺序执行的。main 里面的代码会等待 runBlocking 中的代码执行完毕。

    runBlocking 介绍

    runBlocking 是一个顶层函数,定义在 Builders.kt。
    runBlocking 在内部构造了 newContext 协程上下文,然后调用 start 方法启动。最后使用 joinBlocking 返回。

    @Throws(InterruptedException::class)
    public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T {
        contract {
            callsInPlace(block, InvocationKind.EXACTLY_ONCE)
        }
        val currentThread = Thread.currentThread()
        val contextInterceptor = context[ContinuationInterceptor]
        val eventLoop: EventLoop?
        val newContext: CoroutineContext
        if (contextInterceptor == null) {
            // create or use private event loop if no dispatcher is specified
            eventLoop = ThreadLocalEventLoop.eventLoop
            newContext = GlobalScope.newCoroutineContext(context + eventLoop)
        } else {
            // See if context's interceptor is an event loop that we shall use (to support TestContext)
            // or take an existing thread-local event loop if present to avoid blocking it (but don't create one)
            eventLoop = (contextInterceptor as? EventLoop)?.takeIf { it.shouldBeProcessedFromContext() }
                ?: ThreadLocalEventLoop.currentOrNull()
            newContext = GlobalScope.newCoroutineContext(context)
        }
        val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop)
        coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
        return coroutine.joinBlocking()
    }
    

    runBlocking 的最后一个参数是block: suspend CoroutineScope.() -> T),同时也返回 T。因此它可以返回协程执行结果。

    runBlocking 是对 launch 的一种补充,但由于它是阻塞式的,因此,runBlocking 并不适用于实际的工作当中。

    async

    async 使用

    
    fun main() = runBlocking {
        println("In runBlocking:${Thread.currentThread().name}")
    
        val deferred: Deferred<String> = async {
            println("In async:${Thread.currentThread().name}")
            delay(1000L) // 模拟耗时操作
            return@async "Task completed!"
        }
    
        println("After async:${Thread.currentThread().name}")
    
        val result = deferred.await()
        println("Result is: $result")
    }
    
    

    输出结果

    In runBlocking:main @coroutine#1
    After async:main @coroutine#1 // 注意,它比“In async”先输出
    In async:main @coroutine#2
    Result is: Task completed!
    

    可以看出 async 是非阻塞的,同时用 await 返回执行结果。

    async 介绍

    async 的行为类似钓鱼模式,抛出鱼竿,然后拉回鱼竿。

    public fun <T> CoroutineScope.async(
        context: CoroutineContext = EmptyCoroutineContext,
        start: CoroutineStart = CoroutineStart.DEFAULT,
        block: suspend CoroutineScope.() -> T
    ): Deferred<T> {
        val newContext = newCoroutineContext(context)
        val coroutine = if (start.isLazy)
            LazyDeferredCoroutine(newContext, block) else
            DeferredCoroutine<T>(newContext, active = true)
        coroutine.start(start, coroutine, block)
        return coroutine
    }
    

    async 返回 Deferred 类型,用来获取结果。

    展开全文
  • launch 与async的区别 ...按照顺序启动协程现在有三个协程。想要先启动1之后再启动2 和3如何操作 ,luanch启动的话 使用 join函数 async的话 使用 await join和await 都是挂起函数,都不会阻塞主线程
  • Unity协程与调用函数

    2020-10-29 18:13:31
    // 启动协程 Public Coroutine StartCoroutine(methodName:String); Public Coroutine StartCoroutine(IEnumertator rountine); Public Coroutine StartCoroutine(IEnumertator rountine,Object Value); //终止...
  • Unity协程函数

    2017-07-21 14:12:49
    启动协程函数和停止协程函数参数类型要相同,比如使用协程函数的名字启动协程时,也要使用协程函数的名字停止协程。(Note: Do not mix the two arguments. If a string is used as the argument in StartCoroutine,...
  • Kotlin 协程启动

    千次阅读 2022-03-25 15:42:18
    文章目录Kotlin 协程的启动添加依赖调试协程启动协程launch()runBlockingasync-await总结 Kotlin 协程的启动 添加依赖 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0' 调试协程 设置VM参数...
  • 协程就是用户空间的轻量线程,或者说是用户空间创建的伪线程,既然是创建了线程,就需要实现函数调用。简单来说,协程和线程切换的过程是类似的,只不过是用户空间实现的切换: _st_md_cxt_save:保存当前函数信息...
  • LAZY:只有协程被需要时,包括主动调协程的start、join或者await等函数时,才会开始调度,如果调度前就被取消。那么该协程将直接进入异常状态。UNDISPATCHED:协程创建后立即在当前函数调用栈中执行,直到遇到第一个...
  • 1. 什么是协程 ...在 Python 中协程就是一个可以暂停执行的函数,听起来和生成器的概念一样。 ​ 从 Python3.4 开始协程被加入到标准库,当时的协程是通过 @asyncio.coroutine 和 yeild from 实现的,看起来和生
  • 一,协同函数的定义和启动: –a.用coroutine.create创建一个协程 Co= coroutine.create(function() local c =a+b return c end ) –1.启动coroutine.create定义的函数 coroutine.resume(Co,20,30) b.用coroutine....
  • } } 后面看使用了这个脚本实例的地方的提示,他说是需要用 AddComponent(),改了之后才好了 因为我这个脚本原来是不需要继承 mono 的,所以我当时特意为了协程继承了 mono,但是实例化这个类的代码还是用的 ...
  • 协程启动模式和生命周期
  • Coroutine协程函数 本质上是一个返回类型IEnumerator声明的函数,并且yield return语句包含在函数的某个地方。yield return语句,会执行暂停,并在下一帧从暂停处开始继续执行。 对复杂逻辑进行分帧,可以在主线程...
  • 每个Go程序启动的时候只有一个对用户可见的协程,我们称之为主协程。一个协程可以开启更多其它新的协程。 在Go中,开启一个新的协程是非常简单的,我们只需要在一个函数调用之前使用一个go关键字,即可让此函数调用...
  • Tornado---协程

    2020-02-01 02:54:30
    协程使用Python yield关键字来代替链式回调(在一些像gevent里使用的共生的轻量级的线程也被称作协程,但是Tornado中所有的协程使用显式的上下文切换,被称作异步函数)挂起和继续执行. 协程和异步代码一样简单,但是...
  • 3.协程-挂起函数

    2021-05-31 14:42:56
    上一篇,我们知道了非阻塞挂起的核心是要执行一个挂起函数,挂起函数的作用就是启动线程执行耗时任务,耗时任务执行完毕,通知调用线程继续执行后续的代码。那么我们如何定义挂起函数呢?有哪些方式呢?接下来我们...
  • Kotlin 之 协程(二)启动取消协程

    千次阅读 2022-01-18 12:49:33
    launch和async构建器都用来启动协程 launch,返回一个job并且不附带任何结果值 async,返回一个Deferred,Deferred也是一个job,可以使用.await()在一个延期的值上得到它的最终结果 //等待一个作业:join与await ...
  • go中的协程原理详解

    2022-07-19 14:24:30
    本文主要介绍了go中协程的相关知识。
  • Python协程的四种实现方式

    千次阅读 2022-01-08 14:15:44
    Python协程的四种实现方式
  • Unity的协程详解

    2022-09-08 10:16:43
    Unity中的协程由协程函数和协程调度器两部分构成.协程函数使用的是C#的迭代器, 协程调度器则利用了MonoBehaviour中的生命周期函数来实现. 协程函数实现了分步, 协程调度器实现了分时.注:因为协程分时分步执行的...
  • 关于Go语言的非main函数退出后,其子协程的是否退出这件事一级目录 一级目录
  • 首先承认这个系列有点标题党,Jetpack 的 MVVM 本身没有错...Flow 基于协程实现,具有丰富的操作符,通过这些操作符可以实现线程切换、处理流式数据,相比 LiveData 功能更加强大。 但唯有一点不足,无法像 LiveData ..
  • 本文是我在 2019 年 Android 开发者峰会上与 Yigit Boyar 的谈话总结的第二部分。 ... 第一部分:响应式 UI 第二部分:使用架构组件启动协程(本文) ...这是启动协程最常见的方法之一,因为大多数数
  • 1、协程基础

    2020-12-25 19:29:08
    协程基础 这部分主要包括协程的一些基本概念。 你的第一个协程 贯通阻塞与非阻塞世界 等待执行结果 结构化并发 构建协程作用域 函数提取 轻量级的协程 全局作用域的协程 ...
  • 协程启动和取消

    2022-05-10 00:25:47
    launch与async构建器都用来启动协程 launch,返回一个Job并且不附带任何结果值 async,返回一个Deferred,Deferred也是一个Job,可以使用await()在一个延期的值上得到它的最终结果 等待一个作业 launch通过...
  • Unity3D--协程使用详解

    千次阅读 2022-06-16 10:29:38
    Unity3D--协程使用详解
  • 这篇文章我们来讲协程的使用,简单的使用,毕竟协程是一个很强大的设计模式,深入了解需要花很多的时间,我们先从简单开始,其实学会了简单的使用,基本已经可以满足我们平时的开发需要了,话不多说,开始。
  • Unity中的协程

    千次阅读 2021-11-08 14:56:33
    协程其实就是一个IEnumerator(迭代器),其中必须含有yield return ,yield return语句是一种特殊的返回语句,它可以确保函数在下一次被执行时,不是从头开始,而是从Yield语句处开始。 常用的yield return语句: ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 20,983
精华内容 8,393
热门标签
关键字:

启动协程的函数