.NET中的WebBrowser和线程问题

本文关键字:线程 问题 WebBrowser 中的 NET | 更新日期: 2023-09-27 17:59:23

我目前正在从URL列表中读取HTML源代码,该URL使用JavaScript加载带有需要提取的动态超链接的特定span。除了两个小错误外,一切都很好,但可以在调试过程中处理:

  1. 当到达DocumentCompleted事件时,有时Document.Body为空

  2. 当调用t.Join()时,程序有时会挂起很长一段时间。

    public class WebProcessor
    {
    private string GeneratedSource { get; set; }
    private string URL { get; set; }
    public string GetGeneratedHTML(string url)
    {
        URL = url;
        Thread t = new Thread(new ThreadStart(WebBrowserThread));
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
        t.Join(); 
        return GeneratedSource;
     //When GetGeneratedHTML() is called more than once there is a chance the program 
    //will hang indefinitely maybe even deadlock??
    }
    private void WebBrowserThread()
    {
        WebBrowser wb = new WebBrowser();
       wb.Navigate(URL);
        wb.DocumentCompleted +=
            new WebBrowserDocumentCompletedEventHandler(
                wb_DocumentCompleted);
        while (wb.ReadyState != WebBrowserReadyState.Complete)
            Application.DoEvents();
        wb.Dispose();
    }
    private void wb_DocumentCompleted(object sender,
        WebBrowserDocumentCompletedEventArgs e)
    {
        if(((WebBrowser)sender).Document.Body != null)
        {
            GeneratedSource = ((WebBrowser)sender).Document.Body.InnerHtml;
        }
        else
        {
    //Handle when Document isn't fully loaded
        }
    }
    }
    

.NET中的WebBrowser和线程问题

以下链接可能有助于提供解决当前问题的一些信息,因为它看起来是Application.DoEvents不是一个好的用法,关于它及其替代品有很多讨论:

Application.DoEvents()的使用

Application.DoEvents()的替代方案

Do Events Evil

我的理解是,你发现Document.Body为空,DoEvents可以发挥作用。

关于Join(),它将阻止它的角色,直到点线程返回,我不确定为什么要使用STA作为线程属性,这是访问COM之类的东西所必需的,而COM只能在STA模式下操作。您可能需要检查以下使用Async Await系统执行相同操作的链接,该系统在使UI无线程方面要好得多,并将使您的UI界面响应更快:

是否有适用于WebBrowser的Application.DoEvents()?

理想情况下,现在使用线程已经过时了,最好使用任务API,因为它们在并行化方面做得更好。