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

时间:2013-04-18 22:00:12

标签: c# .net

Steven Toub's article中:

  

使开发人员更容易编写基于的异步代码   任务,.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中未观察到的异常是否仍然会崩溃应用程序?

1 个答案:

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