C#异步/等待未观察到的异常 [英] C# async / await unobserved exception

查看:73
本文介绍了C#异步/等待未观察到的异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解为什么下面的代码:

I'm trying to understand why the following code:

async void Handle_Clicked(object sender, System.EventArgs e)
{
    try
    {
        await CrashAsync("aaa");
    }
    catch (Exception exception)
    {
        Log($"observed exception");

        Log($"Exception: {exception.Message}");
    }
}

private async Task CrashAsync(string title)
{
    Log($"CrashAsync ({title}) - before");

    await Task.Delay(1000);

    throw new Exception($"CrashAsync ({title})");

    Log($"CrashAsync ({title}) - after");
}

产生预期的结果:

线程#1:CrashAsync(aaa)-之前

thread #1: CrashAsync (aaa) - before

线程1:观察到的异常

线程#1:例外:CrashAsync(aaa)

thread #1: Exception: CrashAsync (aaa)

但是如果我将其更改为此:

but if I change it to this one:

async void Handle_Clicked(object sender, System.EventArgs e)
{
    try
    {
        await CrashAsync("aaa").ContinueWith(async (t) =>
        {                   
            await CrashAsync("bbb");
        },TaskContinuationOptions.OnlyOnRanToCompletion);
    }
    catch (Exception exception)
    {
        Log($"observed exception");

        Log($"Exception: {exception.Message}");
    }
}

我得到以下输出:

线程#1:CrashAsync(aaa)-之前

thread #1: CrashAsync (aaa) - before

线程1:观察到的异常

线程#1:异常:任务已取消.

thread #1: Exception: A task was canceled.

线程2:无法观察到的异常

thread #2: unobserved exception

线程#2:System.Exception:CrashAsync(aaa) 在/Users/johndoe/Development/Xamarin/AsyncTest/AsyncTest/AsyncTestPage.xaml.cs:82

thread #2: System.Exception: CrashAsync (aaa) at AsyncTest.AsyncTestPage+c__async3.MoveNext () [0x000ad] in /Users/johndoe/Development/Xamarin/AsyncTest/AsyncTest/AsyncTestPage.xaml.cs:82

其中:

TaskScheduler.UnobservedTaskException += (sender, e) =>
{
    Debug.WriteLine($"thread #{Environment.CurrentManagedThreadId}: unobserved exception");

    foreach (var exception in e.Exception.Flatten().InnerExceptions)
    {
        Debug.WriteLine($"thread #{Environment.CurrentManagedThreadId}: {exception}");
    }
};

不满足延续条件,因此取消了ContinueWith任务,但是为什么我有未观察到的异常?

The continuation condition is not satisfied so the ContinueWith task is cancelled, but why do I have unobserved exception?

推荐答案

您正在等待ContinueWith返回的Task,因此您观察到与此Task相关的异常-已将其取消(TaskCanceledException).但是,您不会观察到CrashAsync引发的原始异常(即"CrashAsync aaa")异常,因此不会观察到您的行为.

You await Task returned by ContinueWith, so you observe exception related to this Task - that it was cancelled (TaskCanceledException). But you don't observe original exception thrown by CrashAsync (so "CrashAsync aaa") exception, hence the behavior you observe.

下面是示例代码,可以帮助您进一步理解:

Here is sample code to get more understanding:

static async void Test() {
    var originalTask = CrashAsync("aaa");
    var onSuccess = originalTask.ContinueWith(async (t) =>
    {
        await CrashAsync("bbb");
    }, TaskContinuationOptions.OnlyOnRanToCompletion);
    var onFault = originalTask.ContinueWith(t => {                    
        Log("Observed original exception: " + t.Exception.InnerExceptions[0].Message);
    }, TaskContinuationOptions.OnlyOnFaulted);
}

因此,简而言之-等待任务并捕获异常(如果有).您根本不需要使用ContinueWith,因为如果您使用await,则该方法的其余部分已经已经了.

So in short - just await your task and catch exception if any. You don't need to use ContinueWith at all, because if you use await - the rest of the method is already a continuation.

这篇关于C#异步/等待未观察到的异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆