can this code be done async?
note that async
is a keyword and a bit misleading here. Ofcourse you can do web requests etc async
but the code would be completely different since most of the Unity API can't be used on threads...
Coroutines are never async
but still run in the main thread like if they were temporary Update
methods. In fact the MoveNext
call for Coroutines is done right after the Update
.
Waiting for multiple WebRequests parallel
So I guess what you rather ment is
can these requests be awaited parallel?
Esiest solution I can imagine where you wouldn't have to change your code structure too much would be to store all UnityWebRequestAsyncOperation
s (what is returned by SendWebRequest
in an array and yield
until all of them are isDone
like e.g.
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;
}
For completeness: WaitUntil
and Linq All
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…