.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()
方法,因此对HttpClient
的GetStringAsync()
方法的调用将抛出一个expcetion,并且它会使应用程序崩溃。
所以我的问题是:默认情况下,.NET 4.5中未观察到的exception是否仍然会崩溃应用程序?
你确实有一个带有exception的Task
( GetStringAsync
返回的那个)。 但是, await
正在观察Task
exception,然后该exception传播出DownloadAsync
方法( async void
)。
从async void
方法传播的exception行为不同; 它们是在async void
方法启动时处于活动状态的SynchronizationContext
上引发的(在本例中是一个线程池SynchronizationContext
)。 这不被视为未被观察到的例外。
如果您更改DownloadAsync
以返回Task
,那么您将获得一个实际未观察到的Task
exception,该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); } }