无法等待的方法异常导致行为不一致 [英] Not awaitable method exception thowing inconsistent behaviour

查看:66
本文介绍了无法等待的方法异常导致行为不一致的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我读了async/await和某处的某处,我读到某个地方,如果您不等待异步方法,那么您基本上会失去它.它会触发并忘记并进入AEeher,如果它引发异常-您将永远不会知道.
这是作者使用的示例:

So I read on async/await and somewhere, someplace I read that if you don't await an async method you basically lose it. It fires and forgets and goes into the AEeher and if it throws an exception - you will never know.
This was the example the author used:

    static async void OnButtonClick()
    {
        yolo();
        string imageUrl = null;
        try
        {
            DownloadAndBlur(imageUrl);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Exception: {ex}");
        }
        Console.WriteLine("Done!");
    }

    static async Task DownloadAndBlur(string url)
    {
        if (url == null)
        {
            throw new ArgumentNullException(nameof(url));
        }
    }

实际上,如果我从代码中调用OnButtonClick()方法,则不会引发任何异常,或者,控制台上不会打印任何有关异常的内容.而如果我等待DownloadAndBlur方法-会将异常写入控制台.

Indeed, if I call the OnButtonClick() method from my code no exception gets thrown, or rather, nothing about an exception is printed on the console. While if I await the DownloadAndBlur method - an exception is written to the console.

所以我试图复制行为并写成这样:

So I tried to replicate the behaviour and wrote this:

    static async void Execute()
    {
        Console.WriteLine(1);
        yolo();
        Console.WriteLine(2);
    }

    static Task yolo()
    {
        throw new Exception();
    }

但是会引发异常,而我的调试会话会捕获该异常.那么有什么不同,因为我认为它们是相同的.

But an exception is thrown and my debugging session catches it. So what is different, because I think they are the same.

推荐答案

Execute方法不是一劳永逸的.它是

The Execute method is not fire-and-forget. It is async void.

static async void Execute()
{
    YoloAsync();
}

async void方法中的异常会在当前SynchronizationContext中引发(或在ThreadPool中,如果

Exceptions in async void methods are thrown in the current SynchronizationContext (or in the ThreadPool if the SynchronizationContext.Current is null), which normally results to the crashing of the process (source code).

接下来,YoloAsync方法未标记为

Next, the YoloAsync method is not marked with the async modifier.

static Task YoloAsync()
{
    throw new Exception();
}

在语义上是一种异步方法,因为它返回了Task,但是任务不是从异步状态机生成的.因此,YoloAsync方法内部的代码与任何其他方法一样被同步执行,并且不同于由异步状态机生成的方法通过它们返回的Task传播其异常.

Semantically it is an asynchronous method since it returns a Task, but the task is not generated from an async-state-machine. So the code inside the YoloAsync method is executed synchronously like any other method, and unlike the async-state-machine-generated methods that propagate their exceptions through the Task they return.

这篇关于无法等待的方法异常导致行为不一致的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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