.NET中的WebBrowser和线程问题
本文关键字:线程 问题 WebBrowser 中的 NET | 更新日期: 2023-09-27 17:59:23
我目前正在从URL列表中读取HTML源代码,该URL使用JavaScript加载带有需要提取的动态超链接的特定span。除了两个小错误外,一切都很好,但可以在调试过程中处理:
-
当到达
DocumentCompleted
事件时,有时Document.Body
为空 -
当调用
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 } } }
以下链接可能有助于提供解决当前问题的一些信息,因为它看起来是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,因为它们在并行化方面做得更好。