我发现这段代码用于在 Unity 中异步加载模型。我想知道它是如何工作的,所以我可以做一些类似的事情来运行一个异步函数并在协程中从中检索一个值。我无法使用相同的结构在网上找到任何东西,但我可能不知道要搜索什么,我认为这个例子没有使用异步流。
我感兴趣的代码是:
IEnumerator Start()
{
AssetBundleCreateRequest bundleLoadRequest = AssetBundle.LoadFromFileAsync(pathToBundle);
yield return bundleLoadRequest;
AssetBundle myLoadedAssetBundle = bundleLoadRequest.assetBundle;
...
}
我不确定什么样的对象“AssetBundleCreateRequest”是用异步函数初始化的,在协程中产生,然后在协程继续时能够提取一个属性。我想在协程中运行我自己的异步函数并在它完成后从中提取返回值。
好吧,在内部 Unity 只是在每一帧创建一个IEnumerator
,yields
直到异步加载任务完成。
你可以例如做类似的事情
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] 删除。
我来说两句