Unity3D如何在同一个方法块中同时异步等待线程和协程

问题

在做Unity3D开发时,在整合UnityEngine的异步方法(协程)同其它Framework(如.Net API、WinRT API)的异步方法(async)给我造成了困扰,因为异步的实现的方式不同。在一个方法中等待一个协程返回使用yield return关键字,并且需要该方法的返回值为IEnumerator;而在一个方法中等待一个async方法返回使用await关键字,并且需要该方法声明为async方法且返回值必须为void、Task或Task。然而同一个方法中只能有一个返回值,所以看起来无法在同一个方法中同时等待协程和线程。

解决

但其实可以利用Task.IsCompleted字段来替换await的异步等待方式,在方法中返回一个WaitUtil对象,即可将线程的异步等待包装为协程的异步等待。例如现在有如下两个异步方法,分别实现自线程和协程:

public async Task<string> ReadAsync(string path) {
    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) {
        using (StreamReader sw = new StreamReader(fs, Encoding.UTF8)) {
            return await sw.ReadToEndAsync();
        }
    }
}
public IEnumerator LoadResourceAsync(string path) {
    yield return Resources.LoadAsync<GameObject>(path);
}

若现在需要实现一个方法,异步等待ReadAsync的结果,并将结果作为参数传递给LoadResourceAsync,则可以这样写:

public IEnumerator TestAsync() {
    Task<string> task = ReadAsync("xxx");
    yield return new WaitUntil(() => {
        return task.IsCompleted;
    });
    string result = task.Result;
    yield return LoadResourceAsync(result);
    Debug.Log("执行完成");
}

然后在MonoBehaviour中进行调用

StartCoroutine(TestAsync());

如有错误欢迎指正交流!

你可能感兴趣的:(Unity3D,Unity3D,异步,协程)