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
    }

但我不知道这是有效的还是优雅的解决方案。如果您对此有任何想法,我将不胜感激。提前谢谢。

C#外部类线程(AutoResetEvent)

这样的东西怎么样:

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主页