我有一个列表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 } }