async/await パターンを使用した例外処理の (そう思われる) かなり有名な問題に取り組んでいます。具体的には、私のコンテキストは HTTP クライアントにありますが、はるかに単純なテストでも試してみましたが、同じように動作します。
以下のプログラムを考えてみましょう。これは、元のアプリのコンテキストを非常に単純化したバージョンです。
class Program
{
    static void Main(string[] args)
    {
        Test();
        Console.Write("Press any key...");
        Console.ReadKey();
        Console.WriteLine();
    }
    static async void Test()
    {
        var c = new MyClient();
        try
        {
            var uri = new Uri("http://www.google.com/"); //valid address
            var s = await c.GetString(uri);
            Console.WriteLine(s.Length);
        }
        catch (WebException ex)
        {
            Console.WriteLine(ex.Message);
        }
        try
        {
            var uri = new Uri("http://www.foo.bah/"); //non-existent address
            var s = await c.GetString(uri);
            Console.WriteLine(s.Length);
        }
        catch (WebException ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}
class MyClient
{
    public async Task<string> GetString(Uri uri)
    {
        var client = new HttpClient();
        return await client.GetStringAsync(uri);
    }
}
プログラムが起動すると、最初の Web サイトのページが文字列としてダウンロードされ、その長さが表示されます。これで問題ありません。その後、無効なアドレスに対して同じ操作が実行されると、クライアントは WebException を発生させます (それが私が望んでいることです) が、キャッチされません。
更新:「キャッチされない」とは、コードが実際には「キャッチ」ブランチを通過せず、例外メッセージをサイレントに表示することを意味します。代わりに、VS IDE によって例外が表示され、デバッグが中断されます。
例外をキャッチする適切な解決策はありますか?
よろしくお願いします。