Ed *_*iro 0 c# webrequest unity-game-engine async-await
请问,这段代码可以异步完成吗?我有问题,因为在代码可以继续之前,所有请求都必须终止,我看到了一些关于如何等待一个孤立的请求,但后来我无法使用循环,我一直在尝试解决这个问题,如果有人可以的话帮帮我吧,太好了。
StartCoroutine(GetTexture());
IEnumerator GetTexture() {
for (int i = 0; i < 10; i++)
{
string url = string.Format("https://galinha.webhost.com/img/{0}.jpg", words[i]);
UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError) {
selectionSprites.Add(sprites[i]);
}
else {
Texture2D myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
Sprite spriteFromWeb = Sprite.Create(myTexture, new Rect(0, 0, myTexture.width, myTexture.height), new Vector2(0, 0));
selectionSprites.Add(spriteFromWeb);
}
}//for
Run Code Online (Sandbox Code Playgroud)
这段代码可以异步完成吗?
请注意,这async是一个关键字,在这里有点误导。当然你可以做网络请求等,async但代码会完全不同,因为大多数 Unity API 不能在线程上使用......
协程永远不会async但仍然在主线程中运行,就像它们是临时Update方法一样。事实上,MoveNext对 Coroutines的调用是在Update.
所以我猜你更喜欢的是什么
可以并行等待这些请求吗?
我能想象到的最简单的解决方案是存储所有UnityWebRequestAsyncOperations(SendWebRequest在数组中返回的内容,yield直到它们都isDone像例如
using System.Linq;
...
IEnumerator GetTexture()
{
var requests = new List<UnityWebRequestAsyncOperation>(10);
// Start all requests
for (var i = 0; i < 10; i++)
{
var url = string.Format("https://galinha.webhost.com/img/{0}.jpg", words[i]);
var www = UnityWebRequestTexture.GetTexture(url);
// starts the request but doesn't wait for it for now
requests.Add(www.SendWebRequest());
}
// Now wait for all requests parallel
yield return new WaitUntil(() => AllRequestsDone(requests));
// Now evaluate all results
HandleAllRequestsWhenFinished(requests);
foreach(var request in requests)
{
request.Dispose();
}
}
private void HandleAllRequestsWhenFinished(List<UnityWebRequestAsyncOperation> requests)
{
for(var i = 0; i < 10; i++)
{
var www = requests[i].webRequest;
if(www.isNetworkError || www.isHttpError)
{
selectionSprites.Add(sprites[i]);
}
else
{
Texture2D myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
Sprite spriteFromWeb = Sprite.Create(myTexture, new Rect(0, 0, myTexture.width, myTexture.height), new Vector2(0, 0));
selectionSprites.Add(spriteFromWeb);
}
}
}
private bool AllRequestsDone(List<UnityWebRequestAsyncOperation> requests)
{
// A little Linq magic
// returns true if All requests are done
return requests.All(r => r.isDone);
// Ofcourse you could do the same using a loop
//foreach(var r in requests)
//{
// if(!r.isDone) return false;
//}
//return true;
}
Run Code Online (Sandbox Code Playgroud)