【发布时间】:2012-01-28 13:50:30
【问题描述】:
如何在后台 STA 线程中创建 System.Windows.Forms.WebBrowser?我尝试使用这样的代码:
var tr = new Thread(wbThread);
tr.SetApartmentState(ApartmentState.STA);
tr.Start();
private void wbThread()
{
CWebBrowser browser = new CWebBrowser();
var text = browser.Navigate("http://site.com", CWebBrowser.EventType.loadCompleted).Body.InnerHtml;
}
CWebBrowser - 自定义类,委托 System.Windows.Forms.WebBrowser 对象导航方法并等待页面完成加载。问题是 System.Windows.Forms.WebBrowser 对象上的 LoadCompleted 事件永远不会引发。我找到了一些解决方案here,但它不起作用(在我的 WPF 应用程序上找不到方法 Application.Run())。
public class CWebBrowser : ContentControl
{
public readonly System.Windows.Forms.WebBrowser innerWebBrowser;
private readonly AutoResetEvent loadCompletedEvent;
private readonly AutoResetEvent navigatedEvent;
public enum EventType
{
navigated, loadCompleted
}
public CWebBrowser()
{
innerWebBrowser = new System.Windows.Forms.WebBrowser();
loadCompletedEvent = new AutoResetEvent(false);
navigatedEvent = new AutoResetEvent(false);
System.Windows.Forms.Integration.WindowsFormsHost host = new System.Windows.Forms.Integration.WindowsFormsHost();
host.Child = innerWebBrowser;
Content = host;
innerWebBrowser.DocumentCompleted +=new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(innerWebBrowser_DocumentCompleted);
innerWebBrowser.Navigated += new System.Windows.Forms.WebBrowserNavigatedEventHandler(innerWebBrowser_Navigated);
}
void innerWebBrowser_Navigated(object sender, System.Windows.Forms.WebBrowserNavigatedEventArgs e)
{
navigatedEvent.Set();
}
void innerWebBrowser_DocumentCompleted(object sender, System.Windows.Forms.WebBrowserDocumentCompletedEventArgs e)
{
if (((sender as System.Windows.Forms.WebBrowser).ReadyState != System.Windows.Forms.WebBrowserReadyState.Complete) || innerWebBrowser.IsBusy)
return;
var doc = innerWebBrowser.Document;
loadCompletedEvent.Set();
}
public System.Windows.Forms.HtmlDocument Navigate(string url, EventType etype)
{
if (etype == EventType.loadCompleted)
loadCompletedEvent.Reset();
else if (etype == EventType.navigated)
navigatedEvent.Reset();
innerWebBrowser.Navigate(url);
if (etype == EventType.loadCompleted)
loadCompletedEvent.WaitOne();
else if (etype == EventType.navigated)
navigatedEvent.WaitOne();
System.Windows.Forms.HtmlDocument doc = null;
Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Background, new Action(
delegate
{
doc = innerWebBrowser.Document;
}));
return doc;
}
}
感谢所有的建议,对不起我的英语不好:o(
【问题讨论】:
-
您正在破坏 STA 合同,线程必须泵送消息循环。 stackoverflow.com/questions/4269800/…
-
为什么使用基于 com 的表单? WPF 控件是 System.Windows.Controls.WebBrowser
-
这段代码的目的是什么?你做这一切只是为了尝试从网站输出 html 吗?
-
我使用 winforms WebBrowser,因为我想使用 ReadyState 属性。我使用 webbrowser 下载页面,执行大量 javascripts。
-
Hans Passant,你能评论你的帖子吗? (发布示例)谢谢
标签: wpf multithreading browser