C#外部类线程(AutoResetEvent)
本文关键字:AutoResetEvent 线程 外部 | 更新日期: 2023-09-27 18:26:44
我在从外部类进行线程处理时遇到问题。我是个新手,所以很多事情对我来说仍然是个谜,所以请记住这一点。
我做了研究,发现了很多关于它的话题,包括:
- 如何休眠线程,直到收到异步函数的回调
- https://www.youtube.com/watch?v=xaaRBh07N34
它看起来很清楚,但仍然对我没有帮助。这是我的代码:
public DownloadContent()
{
adres = @"...";
wb = new WebBrowser();
wb.Navigating += (object sender, WebBrowserNavigatingEventArgs e) => objWait.WaitOne();
wb.DocumentCompleted += (object sender, WebBrowserDocumentCompletedEventArgs e) => objWait.Set(); //Here is the problem
wb.DocumentCompleted += OnDocumentCompleted;
wb.Navigate(adres);
MessageBox.Show("after"); //should print after OnDocumentCompleted
}
private void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//some logic
}
问题是这个WebBrowser类使用单独的线程来导航和完成文档。这并没有错,但我不知道我的主线程应该如何与它通信。我试图让原始线程等待,但出现了一个问题,即应该再次启动它的函数objWait.Set()被当前冻结的主线程调用。我想这才是真正的问题。我尝试了很多奇怪的方法来让它发挥作用:
- 为wb制作另一个线程。导航(…);它没有工作,因为它不能在单个线程上工作
- 只为objWait.Set()创建单独的线程;也不起作用,不知道为什么
- 还有一些更奇怪的事情
我知道这对一些人来说可能是微不足道的,但我已经坚持了几个小时了,我真的不知道该怎么办。所以我会感谢任何帮助。
*******************************************编辑***********************************
谢谢大家的回答。我看到很多人都注意到了我最初的问题,并给了我一些建议,对此我很感激,你让我的工作变得更容易了。话虽如此,这次任务的本质是找出是否有什么好的方法来处理它。无论如何,感谢你的所有建议和指导,一旦我完成了这个小项目,我会更仔细地研究它们(一次一件事)。
我想我可以做这样的事情:
public DownloadContent()
{
...
bool flag = true;
wb.DocumentCompleted += OnDocumentCompleted;
wb.DocumentCompleted += (object sender, WebBrowserDocumentCompletedEventArgs e) => flag = false;
wb.Navigate(adres);
while(flag);
MessageBox.Show("after"); //should print after OnDocumentCompleted
}
但我不知道这是有效的还是优雅的解决方案。如果您对此有任何想法,我将不胜感激。提前谢谢。
这样的东西怎么样:
public DownloadContent()
{
AutoResetEvent ase = new AutoResetEvent(false);
System.Threading.Tasks.Task.Factory.StartNew(()=>
{
adres = @"...";
wb = new WebBrowser();
wb.DocumentCompleted += (object sender, WebBrowserDocumentCompletedEventArgs e) => ase.Set(); //Here is the problem
wb.Navigate(adres);
});
ase.WaitOne();
MessageBox.Show("after"); //should print after OnDocumentCompleted
}
我们在另一个线程中开始下载,并阻止当前线程,直到文档完成。
这不是你问题的直接答案,但根据你的评论,你所要做的只是在一对<p>
标签之间提取文本,那么你的工作就很难了。
更快、更简单、单线程的方法是将WebClient
与"HtmlAgilityPack"一起使用。方法如下:
using (var wc = new System.Net.WebClient())
{
var html = wc.DownloadString(@"http://www.microsoft.com");
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var node = doc.DocumentNode.SelectSingleNode("/html/body/p");
Console.WriteLine(node.InnerText);
}
目前产生的结果是:
您当前的用户代理字符串似乎来自自动过程,如果不正确,请单击此链接:美国英语Microsoft主页