12

「async」と「await」が提供する機能を使用してWebページのコンテンツを非同期にダウンロードしようとしていますが、タスクが完了するのを永遠に待っているという問題が発生しています。次のコードスニペットの何が問題になっているのか教えてください。

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;
}
4

2 に答える 2

20

まず、.NET4.0ではなく.NET4.5で実行していることを確認します。ASP.NETは、async.NET4.5で認識されるようになりました。

次に、適切な解決策は次awaitの結果になりTask.WhenAllます。

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

ASP.NETパイプライン(.NET 4.5のみ)は、コードが実行中であることを検出し、実行が完了するawaitまでその要求を停止します。Page_Load

この状況で使用しているタスクを同期的にブロックすると、ブログで説明しているようにWaitデッドロックが発生します。

于 2013-01-04T18:59:49.260 に答える
1

スティーブン・クリアリー+1。以下に示すように、Page_Loadを使用して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" %>

これが訪問者に役立つことを願っています。

于 2015-10-20T07:20:49.503 に答える