0

我正在冒险进入 WPF - 第一次在 (VB).NET 中 - 并尝试重新创建我在 MS Access VBA 中开始的项目。它基本上是在 Web 应用程序中抓取一系列页面。正如您可能已经猜到的那样,我在 LoadCompleted 事件中遇到了麻烦。

我已经搜索并找到了一些关于它的信息,但是代码的“流程”只适合等待一页加载。例如:

http://social.msdn.microsoft.com/Forums/nn-NO/wpf/thread/52c1bc55-dd41-468c-8759-a42726635d4b

所有代码执行都在 DocumentLoaded 事件中运行,当您只需要导航到一页并执行代码时,该事件就可以正常工作。但是我需要为我的应用程序执行一系列这些循环。

如何可靠地等待文档完全加载,同时仍将代码执行保持在同一个 Sub 中并且不锁定 UI 线程?

这是我正在尝试做的基本想法。

  1. 导航到页面
  2. 等待页面完全加载
  3. 做东西
  4. 导航到页面
  5. 冲洗,重复

PS - .NET 对我来说很新,所以请不要让我的大脑出现堆栈溢出;)

谢谢,布赖恩

-## 编辑 ##-

这就是我在 VBA 中所做的。这正是我想要做的,只是以“.NET”的方式并且不阻塞 UI 线程:

Dim oIE = New SHDocVw.InternetExplorer

        With oIE
            .Navigate(strURL)
            .Visible = False


           ' loop until the page finishes loading
           Do While oIE.Busy : Loop
           Do While oIE.ReadyState <> 4 : Loop

           'Code goes here to read DOM, get fields and click a button (logging in to site)
           'My code execution is done and now I'm ready to go to the next page and read the DOM

           .Navigate(strURL)

        End With

. . . .

就是这样。重复n次。我与每个 DOM 的交互有很大不同。

4

2 回答 2

1

我会在处理程序Navigate结束时再次调用LoadCompleted。然后,我猜,使用窗口范围的变量来跟踪您的目标 URL。

List<string> _urls;
int _i = 0;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
    _urls = new List<string>() { url1, url2, url3 };    // URLs to navigate
    webBrowser1.LoadCompleted += webBrowser1_LoadCompleted;
    webBrowser1.Navigate(_urls[_i]);
}
void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
    // do stuff

    i++;
    var nextUrl = _urls[i];
    webBrowser1.Navigate(nextUrl);
}

编辑

也许像这样的东西会更合适。在每个循环之后,您可以设置下一个 URL 及其处理程序。

class NavIteration
{
    public string Url { get; set; }
    public delegate void HandleResult(object sender, NavigationEventArgs e);
    public HandleResult ResultHandler { get; set; }
}

NavIteration CurrentIteration;

void setNextIteration()
{
    CurrentIteration = null;
    CurrentIteration = new NavIteration() { 
        Url = someurl, 
        ResultHandler = (sender, e) => {
            // handle
        }
    };
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    webBrowser1.LoadCompleted += webBrowser1_LoadCompleted;
    setNextIteration();
    webBrowser1.Navigate();
}

void webBrowser1_LoadCompleted(object sender, NavigationEventArgs e)
{
    CurrentIteration.ResultHandler(sender, e);
    setNextIteration();
    webBrowser1.Navigate(CurrentIteration.Url);
}
于 2012-05-01T14:14:07.727 回答
0

也许我很遥远,但我会在BackGroundWorker. 让主线程除了查找页面之外什么都不做。如果“do stuff”比 find 慢,那么下一个找到油门。

您是否考虑过 WebClient 下载到 String 或 Byte 数组然后转换为 DOM。IE中有你需要的东西吗?

于 2012-05-02T00:33:18.780 回答