1

I have a list of urls in a for loop, loading a url one at a time but FinishLoadingFrameEvent event is called only once.

My complete code is like this

private List<string> urls = //fetch from db;
ManualResetEvent waitEvent = new ManualResetEvent(false);
BrowserView webView = new WPFBrowserView();
string path = //my local path;

public MainWindow()
{
    InitializeComponent();

    mainLayout.Children.Add((UIElement)webView.GetComponent());


    webView.Browser.FinishLoadingFrameEvent += delegate (object sender, FinishLoadingEventArgs e)
    {
        System.Threading.Thread.Sleep(5000);

        if (e.IsMainFrame)
        {
            DOMDocument document = e.Browser.GetDocument();
            var html = document.DocumentElement.InnerHTML;

            System.IO.File.WriteAllText(path, html);
            waitEvent.Set();
        }
    };

    foreach (var url in urls)
    {
            webView.Browser.LoadURL(url);
            waitEvent.WaitOne();
            waitEvent.Reset();
    }
}

Am i missing something?

mathew
  • 185
  • 4
  • 20

1 Answers1

1

Your code seems to work as expected for my set of URLs.

Here is the complete sample code with all the modifications:

public partial class MainWindow : Window
{
    private List<string> urls = new List<string>
        { "google.com", "microsoft.com", "teamdev.com", "teamdev.com/dotnetbrowser" };
    ManualResetEvent waitEvent = new ManualResetEvent(false);
    BrowserView webView = new WPFBrowserView();
    string path = "html.txt";

    public MainWindow()
    {
        InitializeComponent();

        mainLayout.Children.Add((UIElement)webView.GetComponent());


        webView.Browser.FinishLoadingFrameEvent += delegate (object sender, 
            FinishLoadingEventArgs e)
        {
            //System.Threading.Thread.Sleep(5000);

            if (e.IsMainFrame)
            {
                DOMDocument document = e.Browser.GetDocument();
                var html = document.DocumentElement.InnerHTML;

                System.IO.File.WriteAllText(path, html);
                waitEvent.Set();
            }
        };

        foreach (var url in urls)
        {
            Debug.WriteLine($"Loading {url}");
            webView.Browser.LoadURL(url);
            waitEvent.WaitOne();
            Debug.WriteLine($"{url} loaded");
            waitEvent.Reset();
        }
    }
}

You can notice that I have commented out the Thread.Sleep call in the event handler. Uncommenting it simply makes everything run much slower, but it still works.

Anna Dolbina
  • 1
  • 1
  • 8
  • 9
  • I have already tried that, but still FinishLoadingFrameEvent is only called the first time of the loop.. – mathew Sep 28 '17 at 07:56
  • @mathew Is it possible to update the original question with SSCCE that demonstrates the issue? – Anna Dolbina Sep 28 '17 at 08:03
  • I have updated my answer with the modified sample code. It works as expected for my URLs. Note that I have commented out the `Thread.Sleep` call in the event handler. Uncommenting it simply makes everything run slower, but it still works. – Anna Dolbina Sep 28 '17 at 08:44
  • 1
    Truly thankful for all the help and the suggestions, but no luck :( I have the Thread.Sleep because all pages have a loader and requires 2-3 seconds to load the entire page. Maybe this has anything to do with the issue? – mathew Sep 28 '17 at 08:57
  • The `FinishLoadingFrameEvent ` is fired for each and every frame on the web page, not only the main frame. As a result, if you have a page with a significant number of frames, it may take a few minutes to load it completely, because that `Thread.Sleep()` will be performed for each frame. – Anna Dolbina Sep 28 '17 at 09:07
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/155491/discussion-between-mathew-and-anna-dolbina). – mathew Sep 28 '17 at 09:30