.NET 4.5中未观察到的任务exception仍会导致应用程序崩溃

在Steven Toub的文章中 :

为了使开发人员更容易根据Tasks编写异步代码,.NET 4.5更改了未观察到的exception的默认exception行为。 虽然未观察到的exception仍会导致引发UnobservedTaskException事件(不会这样做会发生重大变化),但默认情况下进程不会崩溃。 相反,无论事件处理程序是否观察到exception,exception将在事件引发后最终被吃掉。

但是我的实验结果与上述说法不符。 以下是我的代码:

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

由于我将一个无效的url传递给DownloadAsync()方法,因此对HttpClientGetStringAsync()方法的调用将抛出一个expcetion,并且它会使应用程序崩溃。

所以我的问题是:默认情况下,.NET 4.5中未观察到的exception是否仍然会崩溃应用程序?

你确实有一个带有exception的TaskGetStringAsync返回的那个)。 但是, await正在观察Taskexception,然后该exception传播出DownloadAsync方法( async void )。

async void方法传播的exception行为不同; 它们是在async void方法启动时处于活动状态的SynchronizationContext上引发的(在本例中是一个线程池SynchronizationContext )。 这被视为未被观察到的例外。

如果您更改DownloadAsync以返回Task ,那么您将获得一个实际未观察到的Taskexception,该exception将被忽略(正确):

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