【问题标题】:C# async tasks waiting indefinitelyC# 异步任务无限期等待
【发布时间】:2012-12-18 11:37:48
【问题描述】:

我正在尝试使用“async”和“await”提供的功能来异步下载网页内容,但我遇到了任务永远等待完成的问题。能否请您告诉我以下代码 sn-p 有什么问题?

protected void Page_Load(object sender, EventArgs e)
{
    var websites = new string[] {"http://www.cnn.com","http://www.foxnews.com"};
    var tasks = websites.Select(GenerateSomeContent).ToList();

    //I don't want to use 'await Tasks.WhenAll(tasks)' as I need to block the
    //page load until the all the webpage contents are downloaded
    Task.WhenAll(tasks).Wait();

    //This line is never hit on debugging
    var somevalue = "Complete";
}

static async Task<Results> GenerateSomeContent(string url)
{
    var client = new HttpClient();
    var response = await client.GetAsync(url); //Await for response
    var content = await response.Content.ReadAsStringAsync();
    var output = new Results {Content = content};
    return output;
}

//Sample class to hold results
public class Results
{
    public string Content;
}

【问题讨论】:

  • await vs Task.Wait - Deadlock? 的可能重复项 - 准确描述发生了什么 - awaitWait 是非常不同的事情。
  • 在我的例子中,代码执行停在'Task.WhenAll(tasks).Wait();'这一行

标签: c# asp.net async-await dotnet-httpclient


【解决方案1】:

首先,确保您运行的是 .NET 4.5,而不是 .NET 4.0。 ASP.NET 是在 .NET 4.5 中实现async-aware 的。

那么,正确的解决方案是awaitTask.WhenAll的结果:

var tasks = websites.Select(GenerateSomeContent);
await Task.WhenAll(tasks);

ASP.NET 管道(仅在 .NET 4.5 中)将检测到您的代码是 awaiting,并将停止该请求,直到 Page_Load 运行完成。

在这种情况下使用Wait 同步阻塞任务会导致死锁as I explain on my blog

【讨论】:

  • 在您的博文中,您说要在堆栈中一直使用 async/await...如果它不是一个选项怎么办...您如何正确使用 .Wait()? >
  • @Leonardo:没有适用于所有场景的解决方案,但我在MSDN article on brownfield async 中列举了几个技巧。
【解决方案2】:

+1 斯蒂芬·克利里。刚刚知道您需要在使用 Page_Load 的 void 类型之前进行异步,如下所示:

protected async void Page_Load(object sender, EventArgs e)
{
   var tasks = websites.Select(GenerateSomeContent);
   await Task.WhenAll(tasks);
}

然后在您的代码隐藏文件中(如果 asp.net 网络表单应用程序)也应该具有 Async="true" 属性。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Async="true" Inherits="EmptyWebForm._default" %>

希望这对访问者有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-18
    • 2014-09-06
    • 1970-01-01
    • 2013-02-10
    • 2017-07-22
    • 1970-01-01
    相关资源
    最近更新 更多