跳到主要内容

异步编程支持

winS.Unity.Coroutine 提供完善的 C# Task 支持。

您可以使用协程等待一个 Task,也可以将协程作为 await 的操作数。

在异步方法中等待协程

协程可以被异步等待,您可以用以下方式等待协程:

  • 将协程作为 await 的操作数

    若您只是想在异步方法中等待协程执行完毕,您可以直接将协程作为 await 的操作数使用。

    using UnityEngine;
    using Coroutine = winS.Unity.Coroutine;

    public class Example_ForTask_Await
    {
    public async void Start(Coroutine coroutine)
    {
    await coroutine;
    Debug.Log("End");
    }
    }
  • 将协程转换为 Task

    若您需要等待一个协程并返回一个 Task,您可以在启动协程后通过属性Coroutine.task 获取一个 Task 实例。

    using System.Collections;
    using System.Threading.Tasks;
    using winS.Unity;
    using Coroutine = winS.Unity.Coroutine;

    public class Example_ForTask_GetTask
    {
    public Task Start()
    {
    return Coroutine.Start(MyCoroutine).task;
    }

    private IEnumerator MyCoroutine()
    {
    yield return new Wait(5f);
    }
    }

在协程中等待 Task

您可以在协程中等待一个 Task 实例,如以下代码所示。 需要注意的是,我们不支持 (或者说是禁止) 等待 ValueTask

using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using Coroutine = winS.Unity.Coroutine;

public class Example_ForTask_WaitTask
{
public void Start(Task task)
{
Coroutine.Start(MyCoroutine(task));
}

private IEnumerator MyCoroutine(Task task)
{
yield return task;
Debug.Log("MyCoroutine End");
}
}
为什么禁止等待 ValueTask ?

Unity 巧妙利用了 IEnumerator 来实现单线程协程,通过 IEnumerator.Current 返回的对象来执行不同操作。 但不幸的是,IEnumerator.Current 是一个 object。 若您使用 yield return 返回一个 ValueTask。则会导致装箱。装箱是一个及其昂贵的操作, 不仅抵消了 ValueTask 的性能优势,还有更高的负担。 基于以上考虑,我们决定不予支持对 ValueTask 的等待。