C#:使用异步方法抓取页面

问题描述 投票:0回答:1

我正在为Excel编写插件。我想为excel添加一个新方法,可以抓取网页并获取html代码。

我的问题是我有很多URL要处理,如果我使用同步方法,它将花费大量时间并冻结我的Excel。

比方说,我有一个包含“http://www.google.com”的单元格A1,在A2中,我的方法是“= downloadHtml(A1)”。

我正在使用HttpClient,因为它已经在处理Async。所以这是我的代码:

static void Main()
{
    GetWebPage(new Uri("http://www.google.com"));
}
static async void GetWebPage(Uri URI)
{
    string html = await HttpGetAsync(URI);
    //Do other operations with html code
    Console.WriteLine(html);
}
static async Task<string> HttpGetAsync(Uri URI)
{
    try
    {
        HttpClient hc = new HttpClient();
        Task<Stream> result = hc.GetStreamAsync(URI);

        Stream vs = await result;
        StreamReader am = new StreamReader(vs);

        return await am.ReadToEndAsync();
    }
    catch (WebException ex)
    {
        switch (ex.Status)
        {
            case WebExceptionStatus.NameResolutionFailure:
                Console.WriteLine("domain_not_found");
                break;
            //Catch other exceptions here
        }
    }
    return "";
}

问题是,当我运行程序时,程序在任务完成之前退出。

如果我添加一个

Console.ReadLine();

程序不会退出do到readline指令,几秒后,我看到html打印到我的屏幕(du到console.writeline指令)。所以该计划有效。

我怎么处理这个?

c# asynchronous httpclient
1个回答
0
投票

GetWebPage是一种即发即弃的方法(async void),所以你不能等待它完成。

您应该使用此代替:

static void Main()
{
    string html = Task.Run(() => HttpGetAsync(new Uri("http://www.google.com"))).GetAwaiter().GetResult();
    //Do other operations with html code
    Console.WriteLine(html);
}

此外,您可以将下载代码简化为:

using (var HttpClient hc = new HttpClient())
{
    return await hc.GetStringAsync(URI);
}
© www.soinside.com 2019 - 2024. All rights reserved.