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

Mic*_*sai 12 .net c#

Steven Toub的文章中:

为了使开发人员更容易编写基于Tasks的异步代码,.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);
    }
}
Run Code Online (Sandbox Code Playgroud)

因为我传递一个无效的URL DownloadAsync()方法,调用HttpClientGetStringAsync()方法会抛出一个expcetion,并且它的应用程序崩溃.

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

Ste*_*ary 31

你有一个Task异常(返回的那个GetStringAsync).然而,await正在观察Task异常,然后该异常传播出该DownloadAsync方法(即async void).

传播出async void方法的异常行为不同; 它们是SynchronizationContextasync void方法启动时激活的(在本例中为线程池SynchronizationContext).这被视为未被观察到的例外.

如果您更改DownloadAsync为return 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @ChrisMarisic:是的,我做到了.它可以从[O'Reilly](http://tinyurl.com/ConcurrencyCookbook)或[亚马逊](http://tinyurl.com/ConcurrencyCookbookAmazon)(两个会员链接)获得. (2认同)