C# .NET 4.5中未观察到的任务异常仍会导致应用程序崩溃
在: 使开发人员更容易基于 任务.NET 4.5更改未观察到的任务的默认异常行为 例外情况。而未观察到的例外情况仍将导致 要引发的UnobservedTaskException事件(不这样做将是一个错误) 默认情况下,进程不会崩溃。而是 异常将在事件引发后被吃掉, 不管事件处理程序是否观察到异常 但我的实验结果与上述说法不符。下面是我的代码:C# .NET 4.5中未观察到的任务异常仍会导致应用程序崩溃,c#,.net,C#,.net,在: 使开发人员更容易基于 任务.NET 4.5更改未观察到的任务的默认异常行为 例外情况。而未观察到的例外情况仍将导致 要引发的UnobservedTaskException事件(不这样做将是一个错误) 默认情况下,进程不会崩溃。而是 异常将在事件引发后被吃掉, 不管事件处理程序是否观察到异常 但我的实验结果与上述说法不符。下面是我的代码: static void Main(string[] args) { DownloadAsync("http://an.invalid.url.co
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);
}
}
由于我向downloadsync()
方法传递了无效的url,因此对HttpClient
的GetStringAsync()
方法的调用将抛出一个表达式,并使应用程序崩溃
所以我的问题是:默认情况下,.NET 4.5中未观察到的异常是否仍然会使应用程序崩溃?您确实有一个带有异常的
任务(由GetStringAsync
返回的任务)。但是,await
正在观察任务
异常,该异常随后从downloadsync
方法(即async void
)传播出去
从异步void
方法传播的异常表现不同;它们在异步void
方法启动时处于活动状态的SynchronizationContext
上引发(在本例中,是线程池SynchronizationContext
)。这不被视为未被发现的例外情况
如果将downloadsync
更改为返回Task
,则会出现实际未观察到的Task
异常,该异常将被忽略(正确):
访问文本并非不被观察。长度是一种隐含的等待。@Jesse不是将结果分配给text
,而不是后来使用text.Length
?@MatthewWatson你完全正确,在我看来,这是一项任务,但当然不是。观察异常可以显式地(读取task.Exception属性)或隐式地(使用wait或某个阻塞方法)完成。更多信息:真棒的答案!谢谢大家!@斯蒂芬克利里:信息量很大!这并不是你每天都会遇到的事情,所以我很好奇你是在哪里遇到这种特殊机制的深入知识的。愿意分享这本书或文章吗?@Anthony:.NET reflector,很多问题(主要在MSDN论坛上),以及多年的实验。然而,我目前正在写一本书。:)@斯蒂芬克利里:你真的完成过你的书吗?@chrismaric:是的,我完成了。它可以从或(两个附属链接)获得。
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);
}
}