Home TaskCanceledException thread blocking
Reply: 0

TaskCanceledException thread blocking

user3391
1#
user3391 Published in April 19, 2018, 9:55 am

The following function will work sporadically, but most times blocks the thread at await dlScreenshot_task.

Debug.Log("Downloading from Storage...\n" + url); fires for every image url, then Unity deadlocks. Occasionally it will throw a TaskCanceledException. If the task fails in any way, it should return null for that Task.

public async Task<Texture2D> DownloadScreenshotFromStorageAsync(string url)
{
    byte[] screenshotBytes;
    //Firebase.Storage
    StorageReference cloud = _firebaseStorage.GetReferenceFromUrl(_storageBucketURL + url);
    if( cloud != null ) {
        Task<byte[]> dlScreenshot_task = cloud.GetBytesAsync(1920 * 1080);
        Debug.Log("Downloading from Storage...\n" + url);

        try {    
            screenshotBytes = await dlScreenshot_task;

            if( screenshotBytes != null ) {
                Debug.Log("DLed: " + url);
                return MetaLoader.DeserializeImage(screenshotBytes);
            }
            else {
                return null;
            }
        }
        catch(AggregateException aex ) {
            StorageException store_ex = aex.InnerException as StorageException;
            if(store_ex != null ) { Debug.Log("Storage Exception " + store_ex.ErrorCode); }
            return null;
        }
        catch(TaskCanceledException t ) {
            Debug.LogWarning(t);
            return null;
        }
    }
    else {
        Debug.Log("Cloud Storage Reference failed for " + _storageBucketURL + url);
        return null;
    }
}  

The calling function, using interleaving as found in MSDN Docs regarding Task-based async programming:

private async void DisplayScreenshotsFromDB()
{
    Task<List<string>> dl_task = DownloadURLsAsync();

    List<string> screenshotURLs = await dl_task;

    //Interleaved image downloading
    //https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/consuming-the-task-based-asynchronous-pattern
    List<Task<Texture2D>> imageTasks =
                    (from imageUrl in screenshotURLs select DownloadScreenshotFromStorageAsync(imageUrl)).ToList();
    while( imageTasks.Count > 0 ) {
        Task<Texture2D> imageTask = await Task.WhenAny(imageTasks);
        try {
            imageTasks.Remove(imageTask);

            Texture2D image = await imageTask;
            DisplayScreenshot(image);
        }
        catch (Exception e) {
            imageTasks.Remove(imageTask);
            Debug.Log("Download failed\n" + e);
        }
    }
}

Have I created a race condition that I'm not seeing?
Or why would a caught TaskCanceledException stop the other Tasks from completing?

(It should be a recoverable exception, and a return null is acceptable.)

It may be worth noting that I don't believe the problem lies with the interleaving, calling function. The same trouble occurs if the calling function is structured like this:

Task<List<string>> dl_task = DownloadURLsAsync();

List<string> screenshotURLs = await dl_task;
foreach(string s in screenshotURLs ) {
    await DownloadScreenshotAsync(s);
}
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.747635 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO