如何使用自定义 IEnumerator 类生成协程

亚历克斯

我发现这段代码用于在 Unity 中异步加载模型我想知道它是如何工作的,所以我可以做一些类似的事情来运行一个异步函数并在协程中从中检索一个值。我无法使用相同的结构在网上找到任何东西,但我可能不知道要搜索什么,我认为这个例子没有使用异步流。

我感兴趣的代码是:

    IEnumerator Start()
    {
        AssetBundleCreateRequest bundleLoadRequest = AssetBundle.LoadFromFileAsync(pathToBundle);
        yield return bundleLoadRequest;

        AssetBundle myLoadedAssetBundle = bundleLoadRequest.assetBundle;
        
        ...
     }

我不确定什么样的对象“AssetBundleCreateRequest”是用异步函数初始化的,在协程中产生,然后在协程继续时能够提取一个属性。我想在协程中运行我自己的异步函数并在它完成后从中提取返回值。

雨果

好吧,在内部 Unity 只是在每一帧创建一个IEnumeratoryields直到异步加载任务完成。

你可以例如做类似的事情

public static IEnumerator WaitUntilIsDoneAsync(Action action)
{
    var task = task.Run(() => action?.Invoke());

    while (!task.IsCompleted)
    {
        yield return null;
    }
}

然后你可以等待一些长时间的异步东西通过例如完成

yield return WaitUntilIsDoneAsync(() =>
{
    Thread.Sleep(3000);
}

当然,为了使它更有用,您可能宁愿实现一个类,就像他们所做的那样,您还可以存储任务的结果以供以后访问等。

这当然在很大程度上取决于您希望返回的类型。

它可以例如看起来像这样。请注意,我不是异步专家,并且凭空抓住这个例子......不知道它是否完全像那样工作,但它只是解释在后台或多或少发生的事情。

所以为了yield你只需要any IEnumerator,它不必通过StartCoroutine.

所以你可以通过实施来实现这一点 IEnumerator

public class AsyncFileLoadRequest : IEnumerator
{
    private readonly object _contentLock = new object();
    private Task<string> asyncLoadingTask;

    public string File content
    {
        get
        {
            lock(_contentLock)
            {
                return _fileContent;
            }
        }
    }
    
    public AsyncFileLoadRequest(string path)
    {
        asyncLoadTask = File.ReadAllTextAsync(path);
        AwaitTaskAsync();
    }

    #region IEnumerator implementation

    object IEnumerator.Current => null;

    public void Reset() { }

    public bool MoveNext()
    {
        // As long as this returns true the coroutine will wait
        return !asyncLoadTask.IsCompleted;
    }

    #endregion IEnumerator implementation

    private async void AwaitTaskAsync()
    {
        lock(_contentLock)
        {
            _fileContent = await asyncLoadTask;
        }    
    }
}

所以你可以做类似的事情

var request = new AsyncFileLoadRequest(filePath);

yield return request;

var content = request.FileContent;

或者像他们一样使用工厂方法:

public static class FileIOStuff
{
    public static AsyncFileLoadRequest LoadFileAsync(string path)
    {
        return new AsyncFileLoadRequest (path);
    } 
}

和这样的称呼

var request = FileIOStuff.LoadFileAsync (filePath);

yield return request;

var content = request.FileContent;

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何创建自定义科特林协程在我的ThreadPoolExecutor调度员的工作?

在类中使用ProcessPoolExecutor时无法腌制协程对象

如何使用类自定义解决文件生成冲突

如何使用Gremlin在OrientDB中创建自定义类

F#中的自定义IEnumerator

在非MonoBehaviour类中使用协程

使用IEnumerator遍历列表

如何使用rebot命令生成自定义日志?

使用Kotlin协程时Room dao类出错

协程上下文自定义获取器

在IEnumerator协程中使用闭包进行澄清

如何使用List.Distinct填充自定义类?

如何在Kotlin中使用自定义字体创建TextView的自定义类?

如何使用自定义init创建自定义UINavigationController类?

协程与自定义超时实现

实现IEnumerator接口时,int如何映射到IEnumerator <int>?

PyQt:如何使用自定义消息生成光栅图像

在龙卷风中使用db操作时如何在自定义装饰器中使用协程

如何使用WP生成自定义滑块?

如何在Silex的自定义类中使用$ app?

如何正确使用协程和回调?从 IEnumerator 中检索数组

如何使用 Mockito 使用自定义注释模拟类?

在 IEnumerator 协程中设置类变量

如何在 IEnumerator 中等待或等待,然后继续协程?

IEnumerator.ToArray() 是如何实现的?

如何使自定义类动态使用我的自定义字体?

为什么在使用 IEnumerator 类列表时无法在扩展方法中访问类方法

协程中的自定义适配器

在 IEnumerator 和协程中使用布尔值