Reputation: 21
I'm trying to retrieve the download urls for 2 images from Firebase, in order to pass on to another method as strings to download them.
For a single image, I'm using this code :
img1_ref.GetDownloadUrlAsync().ContinueWith((Task<Uri> task) => {
if (!task.IsFaulted && !task.IsCanceled) {
UnityMainThreadDispatcher.Instance().Enqueue(() => UIcontroller.displayImage(task.Result.ToString()));
}
});
Which works perfectly - but I can't figure out how to fetch two urls, make sure I've got them all, then pass them onto the download method... I'm struggling to get my head around aSync...
Any help grateful received!
Upvotes: 0
Views: 619
Reputation: 3131
If you want to use Continuations, it's relatively straightforward.
First I'd suggest changing your original code to this:
img1_ref.GetDownloadUrlAsync().ContinueWithOnMainThread((Task<Uri> task) => {
if (!task.IsFaulted && !task.IsCanceled) {
UIcontroller.displayImage(task.Result.ToString()));
}
});
This uses a Firebase extension to task to move your logic onto the main thread in a more concise manner.
Next, you can use Task.WhenAll to create a task that waits for multiple tasks to complete:
var task1 = img1_ref.GetDownloadUrlAsync();
var task2 = img2_ref.GetDownloadUrlAsync();
Task.WhenAll(task1, task2).ContinueWithOnMainThread((Task<Uri>[] tasks) => {
if (!task.IsFaulted && !task.IsCanceled) {
// work with tasks here. You can also use IEnumerable<Task<Uri>>
}
});
Of course, now we can have a little fun. I'd recommend reading this article on threading in Firebase for a little more background.
You can use @Frank van Puffelen's answer and do something like this:
async void DownloadAsync() {
var task1 = img1_ref.GetDownloadUrlAsync();
var task2 = img2_ref.GetDownloadUrlAsync();
await Task.WhenAll(task1, task2);
// you're on the calling thread here, which is usually the main thread
UIcontroller.displayImage(task1.Result.ToString());
}
Or you can move this all to a coroutine to get a little bit more Unity-aware memory safety:
IEnumerator DownloadCoroutine() {
var task1 = img1_ref.GetDownloadUrlAsync();
var task2 = img2_ref.GetDownloadUrlAsync();
yield return new WaitUntil(()=>Task.WhenAll(task1, task2).IsComplete);
// coroutines always run on the main thread, and only if this hasn't been destroyed
UIcontroller.displayImage(task1.Result.ToString());
}
Upvotes: 1
Reputation: 598648
Based on Running multiple async tasks and waiting for them all to complete that'd be:
var task1 = img1_ref.GetDownloadUrlAsync();
var task2 = img2_ref.GetDownloadUrlAsync();
await Task.WhenAll(task1, task2);
...
Upvotes: 0