2008-12-15 58 views
0

我有一个WebBrowser控件,它正在从后台STA线程动态地实例化,因为父线程是一个BackgroundWorker并且有很多其他的事情要做。WebBrowser.Navigated仅当我MessageBox.Show();

问题是导航事件从不触发,除非我在告诉它到.Navigate()的方法中弹出一个MessageBox.Show()。我将解释:

ThreadStart ts = new ThreadStart(GetLandingPageContent_ChildThread); 
Thread t = new Thread(ts); 
t.SetApartmentState(ApartmentState.STA); 
t.Name = "Mailbox Processor"; 
t.Start(); 

protected void GetLandingPageContent_ChildThread() 
{ 
WebBrowser wb = new WebBrowser(); 
wb.Navigated += new WebBrowserNavigatedEventHandler(wb_Navigated); 
wb.Navigate(_url); 
MessageBox.Show("W00t"); 
} 

protected void wb_Navigated(object sender, WebBrowserNavigatedEventArgs e) 
{ 
WebBrowser wb = (WebBrowser)sender; // Breakpoint 
HtmlDocument hDoc = wb.Document; 
} 

这工作正常;但是由于这是一个自动化应用程序,所以messagebox将会阻止。当我删除MessageBox.Show()时,WebBrowser.Navigated事件从不触发。我试着用Thread.Sleep()取代这一行,并暂停父线程。我打算在WebBrowser完成它的工作时挂起父线程,并找到一些方法将生成的HTML传递回父线程,以便继续执行更多逻辑。

它为什么这样做?我该如何解决它?

如果有人可以为我提供一种获取网页内容的方法,请填写一些数据,然后在提交按钮的另一端返回页面内容, t支持POST动词,也不通过QueryString传递数据,我也会接受这个答案,因为整个练习都是不必要的。


解决方案:我最终只是没有使用BackgroundWorker和从属线程都在团队建筑师的建议...虽然在响应:(

回答

2

WebBrowser的费用不会做很多,除非它显示,并有一个UI线程关联;您是否显示它所在的表单?您需要,使用DOM等。如果您不想将它显示到屏幕上用户,但它不会在服务中运行良好(例如)。

For scraping purpo ses,你通常可以使用WebClient等模拟一个普通的HTML browwser等等。这是不够的?您可以使用诸如“Fiddler”之类的工具来调查您需要对服务器进行的确切请求。除此之外,您可以查看HTML Agility Pack,它提供了在没有浏览器的情况下对HTML的DOM访问。

+0

否; WebClient和HTTP POST方法都会失败,因为服务器不会' t HTTP 405支持是方法。给定有效载荷时,WebClient也不能通过GET工作。 – tsilb 2008-12-15 20:39:24

+0

那么,网络浏览器必须以某种方式发送*。通过fiddler查看实际的http请求,并以此为起点。 – 2008-12-15 20:42:37

+0

Marc - 我认为这是一个事件问题,而请求的内容并不真正相关。 – TheSoftwareJedi 2008-12-15 20:43:37

0

是否有GUI线程已启动?也许WebBrowser对象使用GUI线程来处理事件。在这种情况下,您应该从创建WebBrowser的线程调用Application.Run()(用此替换您的MessageBox.Show())。 Application.Run()将挂起,直到调用Application.Exit()。

试图现在测试这个。

1

如果WebBrowser的可见性设置为false,则不会触发Navigated和DocumentComplete事件。您可以解决此限制通过使WebBrowser控件可见,但其设置的位置,使得它像用户界面之外:

wb.Visible = true; 
wb.Left = -wb.Width; // notice the minus sign 
0

最后我只是没有使用BackgroundWorker和从属线程都在的建议团队建筑师......虽然在响应:(

1

的费用,你需要添加一行是这样的:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated); 

其中webBrowswer1_Navigated是你要调用的函数,当事件触发

0

WebBrowser控件即可。如果你想在一个线程中使用一个WebBrowser实例,你需要创建你的线程并且调用Thread.SetApartmentState(ApartmentState.STA);