C#外部类线程(AutoResetEvent)

时间:2015-12-15 00:13:59

标签: c# multithreading external autoresetevent

我遇到来自外部类的线程问题。我是一个很新的线程,所以很多事情对我来说仍然是个谜,所以记住这一点。

我做了我的研究,发现了很多关于它的主题,包括:

看起来很清楚,但仍然无法帮助我。这是我的代码:

    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.Navigate(...)制作另一个帖子;它不起作用,因为它无法在单线程上工作;
  • 为objWait.Set()创建单独的线程;也没用,不知道为什么;
  • 甚至更奇怪的东西。

我知道对某些人来说这可能是微不足道的,但我已经坚持了好几个小时了,我真的不知道该怎么办。所以我会感激任何帮助。

********** *** EDIT *********

谢谢大家的回答。我看到很多人都注意到了我原来的问题,并给了我一些建议,我很感激,让你的工作更轻松。可以说,这个任务的本质是找出是否有任何好的方法来处理它。无论如何,谢谢你的所有建议和指示,一旦我完成这个小项目(当时有一件事),我会仔细研究它们。

我想我可以做到这样的事情:

    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
    }

但我不知道这是否被视为有效或优雅的解决方案。对此我有任何想法,我将不胜感激。提前谢谢。

2 个答案:

答案 0 :(得分:0)

这样的事情怎么样:

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
    }

我们在另一个线程中开始下载,并阻止当前线程直到文档完成。

答案 1 :(得分:0)

这不是您问题的直接答案,但根据您的评论说,您所追求的只是在一对<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主页