使用yield return模拟使用Web浏览器导航和等待

时间:2010-09-23 06:10:27

标签: c# .net

我正在处理一个给我带来麻烦的应用程序,部分是因为我调用了一个名为NavigateAndWait(string url)的函数导航,然后在这样的循环中等待:

while(!DocCompleted) Application.DoEvents();

DocCompletedbool,只要调用true,就会更改为DocumentCompleted。我一直在阅读,使用Application.DoEvents()通常是一个坏主意。我也认为是。我使用它主要是作为简化代码的临时方式。问题是我假设会有另一种方法来制作NavigateAndWait函数,并且我根据这个假设制作了整个程序。所以我想出了这种模拟NavigateAndWait函数的方法,而没有实际等待使用yield return。 这只是一个说明这个想法的示例应用程序(请参阅Get()中的Form1)。所以在我继续改变我的整个代码之前,我想知道你的意见。这可能实际上是一个可怕的想法,因为我缺少的东西(我倾向于错过的东西: - ))。

public partial class Form1 : Form
{
    BrowserWrapper bw;

    public Form1()
    {
        InitializeComponent();
        bw = new BrowserWrapper(webBrowser1);
    }

    public IEnumerable<string> Get()
    {
        yield return "www.google.com";      // simulates NavigateAndWait("www.google.com");
        yield return "www.yahoo.com";       // simulates NavigateAndWait("www.yahoo.com");
        yield return "www.hotmail.com";     // simulates NavigateAndWait("www.hotmail.com");
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bw.CallEnumerator(Get());
    }
}

public class BrowserWrapper
{
    WebBrowser Browser;
    IEnumerator<string> Enumerator = null;

    public BrowserWrapper(WebBrowser browser)
    {
        Browser = browser;
        Browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Browser_DocumentCompleted);
    }

    void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if(Browser.ReadyState == WebBrowserReadyState.Complete && e.Url == Browser.Url)
        if (Enumerator != null)
        {
            if (Enumerator.MoveNext()) Browser.Navigate(Enumerator.Current);
        }
    }

    public void CallEnumerator(IEnumerable<string> enumerable)
    {
        Enumerator = enumerable.GetEnumerator();
        if (Enumerator.MoveNext())
        {
            Browser.Navigate(Enumerator.Current);
        }
    }
}

1 个答案:

答案 0 :(得分:2)

这不是最常见的正统方法,但它看起来应该有效。请注意,您应确保迭代器在某个位置处置,例如:

void MoveToNext() {
    if (Enumerator != null)
    {
        if (Enumerator.MoveNext()) Browser.Navigate(Enumerator.Current);
        else {
            Enumerator.Dispose();
            Enumerator = null;
        }
    }
}

(理想情况下也是表格的处理)

但我想知道在数组中保留索引是否更简单?


public partial class Form1 : Form
{
    BrowserWrapper bw;

    public Form1()
    {
        InitializeComponent();
        bw = new BrowserWrapper(webBrowser1);
    }

    public string[] Get()
    {
        return new[] { "www.google.com", "www.yahoo.com", "www.hotmail.com"};
    }

    private void button1_Click(object sender, EventArgs e)
    {
        bw.LoadPages(Get());
    }
}

public class BrowserWrapper
{
    public void LoadPages(string[] pages) {
        this.pages = pages;
        nextIndex = 0;
        NextPage();
    }
    WebBrowser Browser;

    public BrowserWrapper(WebBrowser browser)
    {
        Browser = browser;
        Browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(Browser_DocumentCompleted);
    }

    void Browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
    {
        if(Browser.ReadyState == WebBrowserReadyState.Complete && e.Url == Browser.Url)
        {  NextPage(); }
    }

    string[] pages;
    int nextIndex;
    void NextPage() {
        if(pages != null && nextIndex < pages.Length) {
            Browser.Navigate(pages[nextIndex++]);
        }
    }
}