Skip to main content
 首页 » 编程设计

c#之新线程中的 WebBrowser 控件

2024年01月01日50qq78292959

我有一个要“单击”的 Uri 列表为了实现这一点,我正在尝试为每个 Uri 创建一个新的 Web 浏览器控件。我为每个 Uri 创建一个新线程。我遇到的问题是线程结束在文档完全加载之前,所以我永远无法使用 DocumentComplete 事件。我该如何克服这个问题?

var item = new ParameterizedThreadStart(ClicIt.Click);  
var thread = new Thread(item) {Name = "ClickThread"};  
thread.Start(uriItem); 
 
public static void Click(object o) 
{ 
    var url = ((UriItem)o); 
    Console.WriteLine(@"Clicking: " + url.Link); 
    var clicker = new WebBrowser { ScriptErrorsSuppressed = true }; 
    clicker.DocumentCompleted += BrowseComplete; 
    if (String.IsNullOrEmpty(url.Link)) return; 
    if (url.Link.Equals("about:blank")) return; 
    if (!url.Link.StartsWith("http://") && !url.Link.StartsWith("https://")) 
        url.Link = "http://" + url.Link; 
    clicker.Navigate(url.Link); 
} 

请您参考如下方法:

您必须创建一个泵送消息循环的 STA 线程。对于像 WebBrowser 这样的 ActiveX 组件,这是唯一适合的环境。否则您不会获得 DocumentCompleted 事件。一些示例代码:

private void runBrowserThread(Uri url) { 
    var th = new Thread(() => { 
        var br = new WebBrowser(); 
        br.DocumentCompleted += browser_DocumentCompleted; 
        br.Navigate(url); 
        Application.Run(); 
    }); 
    th.SetApartmentState(ApartmentState.STA); 
    th.Start(); 
} 
 
void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { 
    var br = sender as WebBrowser; 
    if (br.Url == e.Url) { 
        Console.WriteLine("Natigated to {0}", e.Url); 
        Application.ExitThread();   // Stops the thread 
    } 
}