繁体   English   中英

为什么这个异步方法在写入文件之前退出?

[英]Why does this async method quit before writing to file?

我试图了解async/await并编写以下控制台应用程序以下载给定URL的页面内容(基于来自dotnetperls的httpclient示例

什么都没有写入文件。 我在这做错了什么?

static void Main()
{
    AsyncExample();
}

static async void AsyncExample()
{
    Task<string> task = DownloadPageAsync();
    string result = await task;
    WriteToFile(result, someFileName);
}

static async Task<string> DownloadPageAsync()
{
    string page = "http://en.wikipedia.org/wiki/Asynchronous_I/O";
    string result = string.Empty;

    using(HttpClient client = new HttpClient())
    using(HttpResponseMessage response = await client.GetAsync(page))
    using(HttpContent content = response.Content)
    {
        result = await content.ReadAsStringAsync();
    }
    return result;
}

这是因为申请被终止了。 您需要等到AsyncExample完成后才让主要完成它的代码。

目前,Main方法在任务执行之前完成,因此无论任务状态如何,应用程序都会立即终止。

要解决此问题,您需要等到AsyncExample完成。

一种方法是 使用延续然后到 等等 延续 使用Task.Wait()方法的任务。

我们使用延续来处理错误。 从原始任务中读取Result属性将在出错时抛出异常(如果您希望在此处抛出异常,请执行此操作)

但是,如果我们没有使用延续,并且我们没有从故障任务中读取Exception值或Result,那么在完成Task时,应用程序可以终止。 继续处理这两种情况的技巧。

static async Task AsyncExample()
{
    Task<string> task = DownloadPageAsync();
    string result = await task;
    WriteToFile(result, someFileName);
}

public static void Main(string[] args)
{
    var task = AsyncExample();

    task.Wait();
    // task.ContinueWith( t => { }).Wait();
}

对m1o2的回答评论过了一些时间太长了:

但是,如果我们没有使用延续,并且我们没有从故障任务中读取Exception值或Result,那么在完成Task时,应用程序可以终止。

  1. 在TPL中未处理的异常行为方式发生了重大变化。 在.NET 4.0中, UnobservedTaskException将终止您的进程。 在.NET 4.5中它不会 有关这方面的更多信息,请参阅Stephan Toub撰写的this blog post

  2. 没有必要继续。 当使用await task ,编译器将我们的代码提升到一个状态机,稍后在await关键字之后运行任何代码作为“延续”。 如果在等待的任务中发生异常,则一旦任务完成执行,它将被抛出。

  3. 访问Task.Wait将传播AggregationException ,您不必访问Task.ResultTask.Exception 摘自from MSDN

由在本主题后面描述的某些方案除外,在任务内运行的用户代码抛出的未处理异常将传播回连接线程。 当您使用静态或实例Task.WaitTask<TResult>.Wait方法之一时,会传播异常,并通过将调用包含在try-catch语句中来处理它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM