WebBrowser.Naviged 仅在 MessageBox.Show(); 时触发;

发布于 2024-07-09 15:44:10 字数 1233 浏览 3 评论 0原文

我有一个 WebBrowser 控件,它是从后台 STA 线程动态实例化的,因为父线程是一个 BackgroundWorker 并且有很多其他事情要做。

问题是 Navigated 事件永远不会触发,除非我在告诉它 .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.Show() 时,WebBrowser.Naviged 事件永远不会触发。 我尝试用 Thread.Sleep() 替换这一行,并挂起父线程。

一旦解决了这个问题,我打算在 WebBrowser 执行其工作时挂起父线程,并找到某种方法将生成的 HTML 传递回父线程,以便它可以继续执行进一步的逻辑。

为什么要这样做? 我该如何解决这个问题?

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


解决方案:根据团队架构师的建议,我最终根本不使用BackgroundWorker和从属线程......尽管以牺牲响应能力为代价:(

I have a WebBrowser control which is being instantiated dynamically from a background STA thread because the parent thread is a BackgroundWorker and has lots of other things to do.

The problem is that the Navigated event never fires, unless I pop a MessageBox.Show() in the method that told it to .Navigate(). I shall explain:

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;
}

This works fine; but the messagebox will get in the way since this is an automation app. When I remove the MessageBox.Show(), the WebBrowser.Navigated event never fires. I've tried supplanting this line with a Thread.Sleep(), and by suspending the parent thread.

Once I get this out of the way, I intend to Suspend the parent thread while the WebBrowser is doing its job and find some way of passing the resulting HTML back to the parent thread so it can continue with further logic.

Why does it do this? How can I fix it?

If someone can provide me with a way to fetch the content of a web page, fill out some data, and return the content of the page on the other side of the submit button, all against a webserver that doesn't support POST verbs nor passing data via QueryString, I'll also accept that answer as this whole exercise will have been unneccessary.


Solution: I ended up just not using the BackgroundWorker and slave thread at all at the suggestion of the team architect... Though at the expense of responsiveness :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

雨后彩虹 2024-07-16 15:44:10

WebBrowser 不会做太多事情,除非它被显示并且有一个关联的 UI 线程; 您是否显示了它所在的表格? 您需要使用 DOM 等。如果您不想向用户显示表单,则该表单可能会在屏幕外,但它在服务中无法正常工作(例如)。

出于抓取目的,您通常可以使用 WebClient 等模拟常规 HTML 浏览器。这还不够吗? 您可以使用“Fiddler”等工具来调查您需要向服务器发出的确切请求。 除此之外,您还可以查看 HTML Agility Pack,它提供了对 HTML 的 DOM 访问,而无需浏览器。

WebBrowser won't do much unless it is shown and has a UI thread associated; are you showing the form on which it resides? You need to, to use the DOM etc. The form could be off-screen if you don't want to display it to the user, but it won't work well in a service (for example).

For scraping purposes, you can normally simulate a regular HTML browwser using WebClient etc. IS this not sufficient? You can use tools like "Fiddler" to investigate the exact request you need to make to the server. For more than that, you might look at the HTML Agility Pack, which offers DOM access to HTML without a browser.

爱已欠费 2024-07-16 15:44:10

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

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

The Navigated and DocumentComplete events will not fire if the visibility of the WebBrowser is set to false. You can work around this limitation by making the WebBrowser visible but setting it's location so that it is outside of the user interface like:

wb.Visible = true;
wb.Left = -wb.Width; // notice the minus sign
秋日私语 2024-07-16 15:44:10

您需要添加如下行:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);

其中 webBrowswer1_Navierated 是您希望在事件触发时调用的函数。

you need to add a line that's like this:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);

where webBrowswer1_Navigated is the function you want called when the event fires.

昔梦 2024-07-16 15:44:10

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

现在正在尝试测试这一点。

Is there a GUI thread already started? Perhaps the WebBrowser object uses a GUI thread to handle events. In that case, you should call Application.Run() from the thread that creates the WebBrowser (replace your MessageBox.Show() with this). Application.Run() will hang until Application.Exit() is called.

Trying to test this now.

寄意 2024-07-16 15:44:10

根据团队架构师的建议,我最终根本不使用BackgroundWorker和从属线程......尽管以牺牲响应能力为代价:(

I ended up just not using the BackgroundWorker and slave thread at all at the suggestion of the team architect... Though at the expense of responsiveness :(

单调的奢华 2024-07-16 15:44:10

如果 WebBrowser 控件不在 STA 线程中,则该控件无法工作。 如果您想在线程中使用 WebBrowser 实例,您需要创建线程并调用 Thread.SetApartmentState(ApartmentState.STA);

A WebBrowser control can't work if it is not in a STA Thread. If you want to use a WebBrowser instance in a thread you need to create your thread and call Thread.SetApartmentState(ApartmentState.STA);

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文