我正在尝试使用“async”&提供的功能。 “等待”以异步方式下载网页内容,我遇到了任务等待永远完成的问题。您能否告诉我下面的代码片段有什么问题?
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;
}
答案 0 :(得分:19)
首先,确保您运行的是.NET 4.5,而不是.NET 4.0。 ASP.NET在.NET 4.5中被识别为async
。
然后,正确的解决方案是await
Task.WhenAll
的结果:
var tasks = websites.Select(GenerateSomeContent);
await Task.WhenAll(tasks);
ASP.NET管道(仅在.NET 4.5中)将检测到您的代码是await
并将在Page_Load
运行完成之前停止该请求。
在这种情况下使用Wait
同步阻止任务会导致死锁as I explain on my blog。
答案 1 :(得分:1)
+1 Stephen Cleary。刚才开始知道你需要在Page_Load的void类型之前进行async,如下所示:
protected async void Page_Load(object sender, EventArgs e)
{
var tasks = websites.Select(GenerateSomeContent);
await Task.WhenAll(tasks);
}
然后在您的代码隐藏文件(如果是asp.net Web表单应用程序)中也应该有Async =&#34; true&#34;属性。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Async="true" Inherits="EmptyWebForm._default" %>
希望这有助于访客。