我正在尝试创建一个函数来从多个页面获取源代码。抓取每一页后,我想更新表单上的标签,指示进度(5 个中的 1 个、5 个中的 2 个等)。
但是,无论我尝试什么,GUI 都会完全冻结,直到for
循环结束。
public List<List<string>> GetPages(string base_url, int num_pages)
{
var pages = new List<List<string>>();
var webGet = new HtmlWeb();
var task = Task.Factory.StartNew(() => {
for (int i = 0; i <= num_pages; i++)
{
UpdateMessage("Fetching page " + i + " of " + num_pages + ".");
var page = new List<string>();
var page_source = webGet.Load(url+i);
// (...)
page.Add(url+i);
page.Add(source);
pages.Add(page);
}
});
task.Wait();
return pages;
}
对该方法的调用如下所示:
List<List<string>> pages = site.GetPages(url, num_pages);
如果我删除task.Wait();
GUI 解冻,标签会正确更新,但代码会在没有所需的多维列表的情况下继续。
我应该说我对 C# 很陌生。我到底做错了什么?
更新
根据达林,我改变了我的方法:
public async Task<List<List<string>>> GetPages(string url, int num_pages)
{
var pages = new List<List<string>>();
var webGet = new HtmlWeb();
for (int i = 0; i <= num_pages; i++)
{
UpdateMessage("Fetching page " + i + " of " + num_pages + ".");
var page = new List<string>();
var page_source = webGet.Load(url+i);
// (...)
page.Add(url+i);
page.Add(source);
pages.Add(page);
}
return pages;
}
和电话:
List<List<string>> pages = await site.GetPages(url, num_pages);
但是,现在我收到此错误:
'await' 运算符只能在异步方法中使用。考虑使用“异步”修饰符标记此方法并将其返回类型更改为“任务”。
但是当我用异步标记方法时,GUI 仍然冻结。
更新 2
哎呀!我似乎错过了一段达林的新方法。我现在已经包含await webGet.LoadAsync(url + i);
在方法中。我还将我从中调用的方法标记为async
.
现在,不幸的是,我收到了这个错误:
“HtmlWeb”不包含“LoadAsync”的定义,并且找不到接受“HtmlWeb”类型的第一个参数的扩展方法“LoadAsync”(您是否缺少 using 指令或程序集引用?)
我检查过,我使用的是 .NET 4.5.2,我的参考资料中的 HtmlAgilityPack 是 Net45 版本。我不知道现在发生了什么。