Задачи 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;
}
Ответы
Ответ 1
Сначала убедитесь, что вы используете .NET 4.5, а не .NET 4.0. ASP.NET был создан async
-aware в .NET 4.5.
Тогда правильное решение будет await
результатом Task.WhenAll
:
var tasks = websites.Select(GenerateSomeContent);
await Task.WhenAll(tasks);
Конвейер ASP.NET(только в .NET 4.5) обнаружит, что ваш код await
ing и остановит этот запрос до завершения Page_Load
.
Синхронная блокировка задачи с использованием Wait
в этой ситуации вызывает тупик как я объясняю в своем блоге.
Ответ 2
+1 Стивен Клири. Просто узнал, что вам нужно асинхронно до типа void с помощью Page_Load, как показано ниже:
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" %>
Надеюсь, это поможет посетителям.