使开发人员更容易编写基于的异步代码 任务,.NET 4.5更改未观察到的默认异常行为 例外。虽然未观察到的异常仍将导致 要引发的UnobservedTaskException事件(不这样做会是一个 破坏更改),默认情况下进程不会崩溃。相反, 异常将在事件发生后最终被吃掉, 无论事件处理程序是否遵守该异常。
但我的实验结果与上述说法不符。以下是我的代码:
static void Main(string[] args)
{
DownloadAsync("http://an.invalid.url.com);
}
async static void DownloadAsync(string url)
{
using (var client = new System.Net.Http.HttpClient())
{
string text = await client.GetStringAsync(url);
Console.WriteLine("Downloaded {0} chars", text.Length);
}
}
由于我将无效的网址传递给DownloadAsync()
方法,因此对HttpClient
的{{1}}方法的调用将引发一次展示,并使应用程序崩溃。
所以我的问题是:默认情况下,.NET 4.5中未观察到的异常是否仍然会崩溃应用程序?
答案 0 :(得分:27)
你的Task
有一个例外(由GetStringAsync
返回的那个)。但是,await
正在观察Task
异常,然后该异常会从DownloadAsync
方法(async void
)传播出来。
从async void
方法传播的异常行为不同;它们是在SynchronizationContext
方法启动时处于活动状态的async void
上引发的(在本例中为线程池SynchronizationContext
)。这不被视为未被观察到的异常。
如果您更改DownloadAsync
以返回Task
,那么您将获得一个实际未被观察到的Task
例外,该例外将被忽略(正确):
static void Main(string[] args)
{
DownloadAsync("http://an.invalid.url.com);
Console.ReadKey();
}
async static Task DownloadAsync(string url)
{
using (var client = new System.Net.Http.HttpClient())
{
string text = await client.GetStringAsync(url);
Console.WriteLine("Downloaded {0} chars", text.Length);
}
}