How to handle exceptions with ContinueWith and WhenAll?












-1















I am trying to load multiple files asynchronously and inform UI when ever each file is done loading,



_loadCancellationTokenSource = new CancellationTokenSource();

TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var files = await picker.PickMultipleFilesAsync();
LoadedFiles.Clear();

loads = await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsCompleted) LoadedFiles.Add(file.Path);
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, scheduler);
return load;
}));

private Task<Foo> LoadAsync(StorageFile file)
{
// exception may be thrown inside load
return Load(file, _loadCancellationTokenSource.Token);
}


The problem Is when exception is thrown, it is not handled. I know why, because ContinueWith creates a new task but im returning the old task.



This is because ContinueWith is a void task. but I dont know how to return the result correctly. Im not sure if its safe to use t.Result because it may block the UI thread?





PS, I've tried this code but I get a task was cancelled exception and app crashes even though I'm not cancelling any tasks. only a few exceptions are thrown for loading some files.



load = (await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.NotOnRanToCompletion, scheduler);
return load.ContinueWith(t =>
{
LoadedFiles.Add(file.Path);
return (file, t.Result);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler); ;
})));









share|improve this question




















  • 1





    IsCompleted will be true even if IsFaulted or IsCancelled are true. While TaskStatus.RanToCompletion will be true only when IsFaulted and IsCancelled are false. You could add some conditions to ContinueWith handling different TaskContinuationOptions.

    – Jimi
    Jan 1 at 6:01


















-1















I am trying to load multiple files asynchronously and inform UI when ever each file is done loading,



_loadCancellationTokenSource = new CancellationTokenSource();

TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var files = await picker.PickMultipleFilesAsync();
LoadedFiles.Clear();

loads = await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsCompleted) LoadedFiles.Add(file.Path);
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, scheduler);
return load;
}));

private Task<Foo> LoadAsync(StorageFile file)
{
// exception may be thrown inside load
return Load(file, _loadCancellationTokenSource.Token);
}


The problem Is when exception is thrown, it is not handled. I know why, because ContinueWith creates a new task but im returning the old task.



This is because ContinueWith is a void task. but I dont know how to return the result correctly. Im not sure if its safe to use t.Result because it may block the UI thread?





PS, I've tried this code but I get a task was cancelled exception and app crashes even though I'm not cancelling any tasks. only a few exceptions are thrown for loading some files.



load = (await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.NotOnRanToCompletion, scheduler);
return load.ContinueWith(t =>
{
LoadedFiles.Add(file.Path);
return (file, t.Result);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler); ;
})));









share|improve this question




















  • 1





    IsCompleted will be true even if IsFaulted or IsCancelled are true. While TaskStatus.RanToCompletion will be true only when IsFaulted and IsCancelled are false. You could add some conditions to ContinueWith handling different TaskContinuationOptions.

    – Jimi
    Jan 1 at 6:01
















-1












-1








-1








I am trying to load multiple files asynchronously and inform UI when ever each file is done loading,



_loadCancellationTokenSource = new CancellationTokenSource();

TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var files = await picker.PickMultipleFilesAsync();
LoadedFiles.Clear();

loads = await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsCompleted) LoadedFiles.Add(file.Path);
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, scheduler);
return load;
}));

private Task<Foo> LoadAsync(StorageFile file)
{
// exception may be thrown inside load
return Load(file, _loadCancellationTokenSource.Token);
}


The problem Is when exception is thrown, it is not handled. I know why, because ContinueWith creates a new task but im returning the old task.



This is because ContinueWith is a void task. but I dont know how to return the result correctly. Im not sure if its safe to use t.Result because it may block the UI thread?





PS, I've tried this code but I get a task was cancelled exception and app crashes even though I'm not cancelling any tasks. only a few exceptions are thrown for loading some files.



load = (await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.NotOnRanToCompletion, scheduler);
return load.ContinueWith(t =>
{
LoadedFiles.Add(file.Path);
return (file, t.Result);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler); ;
})));









share|improve this question
















I am trying to load multiple files asynchronously and inform UI when ever each file is done loading,



_loadCancellationTokenSource = new CancellationTokenSource();

TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
var files = await picker.PickMultipleFilesAsync();
LoadedFiles.Clear();

loads = await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsCompleted) LoadedFiles.Add(file.Path);
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, scheduler);
return load;
}));

private Task<Foo> LoadAsync(StorageFile file)
{
// exception may be thrown inside load
return Load(file, _loadCancellationTokenSource.Token);
}


The problem Is when exception is thrown, it is not handled. I know why, because ContinueWith creates a new task but im returning the old task.



This is because ContinueWith is a void task. but I dont know how to return the result correctly. Im not sure if its safe to use t.Result because it may block the UI thread?





PS, I've tried this code but I get a task was cancelled exception and app crashes even though I'm not cancelling any tasks. only a few exceptions are thrown for loading some files.



load = (await Task.WhenAll(files.Select(file =>
{
var load = LoadAsync(file);
load.ContinueWith(t =>
{
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.NotOnRanToCompletion, scheduler);
return load.ContinueWith(t =>
{
LoadedFiles.Add(file.Path);
return (file, t.Result);
}, _loadCancellationTokenSource.Token, TaskContinuationOptions.OnlyOnRanToCompletion, scheduler); ;
})));






c# asynchronous exception-handling task result






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 1 at 6:27







M.kazem Akhgary

















asked Jan 1 at 5:39









M.kazem AkhgaryM.kazem Akhgary

12.1k53473




12.1k53473








  • 1





    IsCompleted will be true even if IsFaulted or IsCancelled are true. While TaskStatus.RanToCompletion will be true only when IsFaulted and IsCancelled are false. You could add some conditions to ContinueWith handling different TaskContinuationOptions.

    – Jimi
    Jan 1 at 6:01
















  • 1





    IsCompleted will be true even if IsFaulted or IsCancelled are true. While TaskStatus.RanToCompletion will be true only when IsFaulted and IsCancelled are false. You could add some conditions to ContinueWith handling different TaskContinuationOptions.

    – Jimi
    Jan 1 at 6:01










1




1





IsCompleted will be true even if IsFaulted or IsCancelled are true. While TaskStatus.RanToCompletion will be true only when IsFaulted and IsCancelled are false. You could add some conditions to ContinueWith handling different TaskContinuationOptions.

– Jimi
Jan 1 at 6:01







IsCompleted will be true even if IsFaulted or IsCancelled are true. While TaskStatus.RanToCompletion will be true only when IsFaulted and IsCancelled are false. You could add some conditions to ContinueWith handling different TaskContinuationOptions.

– Jimi
Jan 1 at 6:01














1 Answer
1






active

oldest

votes


















0














Thanks to @Jimi I was able to solve this problem by looking at Task status.



loads = (await Task.WhenAll(files.Select(file =>
{
return LoadAsync(file).ContinueWith(t =>
{
if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);

if (t.Status == TaskStatus.RanToCompletion)
{
LoadedFiles.Add(file.Path);
return t.Result;
}

return null;
}, scheduler);
}))).Where(x => x != null).ToArray();





share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53993244%2fhow-to-handle-exceptions-with-continuewith-and-whenall%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Thanks to @Jimi I was able to solve this problem by looking at Task status.



    loads = (await Task.WhenAll(files.Select(file =>
    {
    return LoadAsync(file).ContinueWith(t =>
    {
    if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
    if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);

    if (t.Status == TaskStatus.RanToCompletion)
    {
    LoadedFiles.Add(file.Path);
    return t.Result;
    }

    return null;
    }, scheduler);
    }))).Where(x => x != null).ToArray();





    share|improve this answer




























      0














      Thanks to @Jimi I was able to solve this problem by looking at Task status.



      loads = (await Task.WhenAll(files.Select(file =>
      {
      return LoadAsync(file).ContinueWith(t =>
      {
      if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
      if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);

      if (t.Status == TaskStatus.RanToCompletion)
      {
      LoadedFiles.Add(file.Path);
      return t.Result;
      }

      return null;
      }, scheduler);
      }))).Where(x => x != null).ToArray();





      share|improve this answer


























        0












        0








        0







        Thanks to @Jimi I was able to solve this problem by looking at Task status.



        loads = (await Task.WhenAll(files.Select(file =>
        {
        return LoadAsync(file).ContinueWith(t =>
        {
        if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
        if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);

        if (t.Status == TaskStatus.RanToCompletion)
        {
        LoadedFiles.Add(file.Path);
        return t.Result;
        }

        return null;
        }, scheduler);
        }))).Where(x => x != null).ToArray();





        share|improve this answer













        Thanks to @Jimi I was able to solve this problem by looking at Task status.



        loads = (await Task.WhenAll(files.Select(file =>
        {
        return LoadAsync(file).ContinueWith(t =>
        {
        if (t.IsFaulted) NotifyUser(t.Exception.Message, NotifyType.ErrorMessage);
        if (t.IsCanceled) NotifyUser("operation was canceled.", NotifyType.ErrorMessage);

        if (t.Status == TaskStatus.RanToCompletion)
        {
        LoadedFiles.Add(file.Path);
        return t.Result;
        }

        return null;
        }, scheduler);
        }))).Where(x => x != null).ToArray();






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 1 at 6:50









        M.kazem AkhgaryM.kazem Akhgary

        12.1k53473




        12.1k53473
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53993244%2fhow-to-handle-exceptions-with-continuewith-and-whenall%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            Npm cannot find a required file even through it is in the searched directory