I use a utility class for my async/await conditionals. I have slightly modified it for your use case (untested):
public static class TaskUtility
{
private static readonly int DeltaTime;
static TaskUtility()
{
DeltaTime = 1000 / MainCamera.instance.MaxFrameRate;
}
/// <summary>
/// Whiles while the function is true
/// </summary>
/// <param name="condition">The function to check</param>
public static async Task WaitWhile(Func<bool> condition)
{
while (condition() && Application.isPlaying)
{
await Task.Delay(DeltaTime);
}
}
/// <summary>
/// Waits until the function is true
/// </summary>
/// <param name="condition">The function to wait on</param>
public static async Task WaitUntil(Func<bool> condition)
{
while (!condition() && Application.isPlaying)
{
await Task.Delay(DeltaTime);
}
}
}
Which would change your code to:
public static async Task<Texture2D> DownloadTexture(string uri)
{
using (
UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(uri, true)
)
{
var asyncOp = uwr.SendWebRequest();
if (WeatherTracker.instance == null)
{
uwr.Abort(); // todo: something related to this is crashing the editor while textures are still being download @jkr
return null;
}
await TaskUtility.WaitUntil(() => asyncOp.isDone);
// return this.uwr.SendWebRequest();
// Debug.Log($"download tex {z}/{x}/{y}");
if (uwr.result != UnityWebRequest.Result.Success)
{
Debug.LogError($"{uwr.error}: {uri}");
return null;
}
else
{
return DownloadHandlerTexture.GetContent(uwr);
}
}
}
This should effectively do the same thing as your code, except it pretends the condition is complete (which is a lie) if you press stop in the editor. (Note: It may behave differently on build.)
It is slightly hacky. Using cancellation tokens as commented by @DMGregory is probably the better way to go. But I have been using this method for a few years without issue. (But I think I'll will probably dehackify it, and update this answer when I do.)