为什么此IOException不抛出异步方法?

时间:2018-07-20 23:34:04

标签: c# asynchronous

我在异步方法中有以下代码块:

private async Task DownloadAsync(string url, string filepath)
{
    var response = await Client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);

    using (Stream stream = await response.Content.ReadAsStreamAsync())
    {
        using (FileStream fs = new FileStream(filepath, FileMode.Create))
        {
            await stream.CopyToAsync(fs);
        }
    }
}

它被这样称呼:

List<Task> tasks = new List<Task>();
tasks.Add(DownloadAsync("https://...", "c:\path\on\disk"));
...    
await Task.WhenAll(tasks);

如果文件正在使用中,FileStream应该抛出IOException。而且,如果我将此块放入try-catch中,则确实可以捕获它。

但是,如果我不处理它,该应用程序不会崩溃或引发异常。它什么都不做。

我是否必须以某种方式手动检查异步任务上的异常?还是还有其他我不理解的东西?

编辑:添加了它的调用方式和更多上下文信息

1 个答案:

答案 0 :(得分:2)

async方法遇到未处理的异常时,该异常被临时存储,然后在等待该方法的任务时引发。这个简单的例子演示了:

public static async Task Foo()
{
    Console.WriteLine("Simulating async with a tiny delay");
    await Task.Delay(1);

    Console.WriteLine("Throwing");
    throw new Exception("Foo");
}   

public static async Task MainAsync()
{
    List<Task> tasks = new List<Task>();

    Console.WriteLine("Adding task");
    tasks.Add(Foo());

    Console.WriteLine("Waiting one second");
    await Task.Delay(1000);

    Console.WriteLine("Awaiting task");
    await Task.WhenAll(tasks);
}


public static void Main()
{
    MainAsync().GetAwaiter().GetResult();
}

输出:

Adding task
Simulating async with a tiny delay
Waiting one second
Throwing
Awaiting task
Run-time exception (line 15): Foo

如您所见,控制台会记录“ Throwing”,但不会引发任何异常。而是在控制台记录“正在等待任务”之后,将其抛出。

Demo on DotNetFiddle