0

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

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

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

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

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


解决方案:在团队架构师的建议下,我最终根本没有使用 BackgroundWorker 和从属线程......虽然以牺牲响应性为代价:(

4

6 回答 6

2

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

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

于 2008-12-15T20:37:42.670 回答
1

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

wb.Visible = true;
wb.Left = -wb.Width; // notice the minus sign
于 2008-12-16T13:47:36.227 回答
1

你需要添加这样一行:

webBrowser1.Navigated += new WebBrowserNavigatedEventHandler(webBrowser1_Navigated);

webBrowswer1_Navigated事件触发时要调用的函数在哪里。

于 2010-05-29T03:44:48.987 回答
0

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

现在试图测试这个。

于 2008-12-15T20:41:04.020 回答
0

在团队架构师的建议下,我最终完全没有使用 BackgroundWorker 和从属线程......虽然以牺牲响应性为代价:(

于 2008-12-16T20:35:09.443 回答
0

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

于 2012-05-02T17:27:24.930 回答