无法等待的方法异常导致行为不一致 [英] Not awaitable method exception thowing inconsistent behaviour
问题描述
所以我读了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.
推荐答案
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).
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屋!