我正在为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指令)。所以该计划有效。
我怎么处理这个?
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);
}