C# 如何处理ContinueWith和WhenAll异常?

C# 如何处理ContinueWith和WhenAll异常?,c#,asynchronous,exception-handling,task,C#,Asynchronous,Exception Handling,Task,我正在尝试异步加载多个文件,并在加载完每个文件后通知UI _loadCancellationTokenSource = new CancellationTokenSource(); TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext(); var files = await picker.PickMultipleFilesAsync(); LoadedFiles.Clear(); loads =

我正在尝试异步加载多个文件,并在加载完每个文件后通知UI

_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);
}

多亏了@Jimi,我才能够通过查看任务状态来解决这个问题

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();

IsCompleted
将为
true
,即使
IsFaulted
IsCancelled
true
。而
TaskStatus.RanToCompletion
只有在
IsFaulted
IsCancelled
为false时才为true。您可以添加一些条件以继续处理不同的问题。
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();