C# 异步任务无限期等待

C# 异步任务无限期等待,c#,asp.net,async-await,dotnet-httpclient,C#,Asp.net,Async Await,Dotnet Httpclient,我正在尝试使用“async”和“await”提供的功能异步下载网页内容,我遇到了一些问题,这些问题的任务将永远等待完成。您能告诉我下面的代码片段有什么问题吗 protected void Page_Load(object sender, EventArgs e) { var websites = new string[] {"http://www.cnn.com","http://www.foxnews.com"}; var tasks = websites.Select(Gen

我正在尝试使用“async”和“await”提供的功能异步下载网页内容,我遇到了一些问题,这些问题的任务将永远等待完成。您能告诉我下面的代码片段有什么问题吗

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;
}
受保护的无效页面加载(对象发送方,事件参数e)
{
var websites=新字符串[]{”http://www.cnn.com","http://www.foxnews.com"};
var tasks=websites.Select(GenerateSomeContent.ToList();
//我不想使用“wait Tasks.WhenAll(Tasks)”,因为我需要阻止
//页面加载,直到下载所有网页内容
Task.WhenAll(tasks.Wait();
//这一行在调试时从未出现过
var somevalue=“完成”;
}
静态异步任务GenerateSomeContent(字符串url)
{
var client=新的HttpClient();
var response=await client.GetAsync(url);//等待响应
var content=await response.content.ReadAsStringAsync();
var输出=新结果{Content=Content};
返回输出;
}
//用于保存结果的示例类
公开课成绩
{
公共字符串内容;
}

首先,确保您运行的是.NET 4.5,而不是.NET 4.0。ASP.NET在.NET 4.5中实现了异步

然后,正确的解决方案是等待任务的结果。当

var tasks = websites.Select(GenerateSomeContent);
await Task.WhenAll(tasks);
ASP.NET管道(仅在.NET 4.5中)将检测到您的代码正在等待,并将暂停该请求,直到
页面加载运行完成


在这种情况下,使用
Wait
同步阻塞任务会导致死锁。

+1 Stephen Cleary。刚知道您需要使用async before void类型和页面加载,如下所示:

protected async void Page_Load(object sender, EventArgs e)
{
   var tasks = websites.Select(GenerateSomeContent);
   await Task.WhenAll(tasks);
}
然后在代码隐藏文件中(如果是asp.net web表单应用程序),也应该具有Async=“true”属性

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


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

可能的重复-准确描述发生了什么-
Wait
Wait
是非常不同的事情。在我的示例中,代码执行在“Task.whalll(tasks).Wait();”行暂停在你的博客文章中,你说在整个堆栈中使用async/await。。。如果这不是一个选项怎么办。。。如何正确地使用
.Wait()
?@Leonardo:没有一种解决方案可以适用于每种情况,但我列举了一个例子中的几种破解方法。