2

I have this code which simply navigates to a website

class BrowsingUrl {
    private System.Windows.Forms.WebBrowser nBrowser ;
        private  System.Windows.Forms.Form theFormLayout1;

    public BrowsingUrl(System.Windows.Forms.Form theFormLayout) {

            this.nBrowser = new System.Windows.Forms.WebBrowser();
            this.nBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
            this.nBrowser.Location = new System.Drawing.Point(0, 0);
            this.nBrowser.MinimumSize = new System.Drawing.Size(20, 20);
            this.nBrowser.Name = "webBrowser1";
            this.nBrowser.ScrollBarsEnabled = false;
            this.nBrowser.Size = new System.Drawing.Size(1300, 700);
            this.nBrowser.TabIndex = 0;
            this.theFormLayout1 = theFormLayout;
            this.theFormLayout1.Controls.Add(this.nBrowser);
            this.nBrowser.Navigate("https://stackoverflow.com");
            this.nBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.nBrowser_DocumentCompleted);
   }

   private void nBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
   {

        // do stuff
   }
}    

If a create one browsingurl object everything works fine but if create two objects it seems to be that the two constructors runs at the same time how can I let the second object wait until the first one end execution

public partial class Form1 : Form
{
        public Form1()
        {
            InitializeComponent();
        }

        private void startbtn_Click(object sender, EventArgs e)
        {
            BrowsingUrl BrowsingUrl1 = new BrowsingUrl(this);
            //wait till browsingUrl1 finish
            BrowsingUrl BrowsingUrl2 = new BrowsingUrl(this);
        }
}    
John Saunders
  • 160,644
  • 26
  • 247
  • 397
magicalll
  • 21
  • 3
  • possible duplicate of [C# how to wait for a webpage to finish loading before continuing](http://stackoverflow.com/questions/583897/c-sharp-how-to-wait-for-a-webpage-to-finish-loading-before-continuing) – Vojtěch Dohnal Sep 28 '14 at 15:47
  • unfortunately not the same problem – magicalll Sep 28 '14 at 15:52
  • I think @magicalll want to wait for the first `nBrowser_DocumentCompleted` to finish before start the second constructor. – kennyzx Sep 28 '14 at 15:53

1 Answers1

0

Set the value of _isLoaded to true in nBrowser_DocumentCompleted and make it accessible as a public property. Also add ScriptErrorsSuppressed = true.

    class BrowsingUrl
    {
        private System.Windows.Forms.WebBrowser nBrowser;
        private System.Windows.Forms.Form theFormLayout1;
        private bool _isLoaded = false;
        public bool IsLoaded
        {
            get { return _isLoaded && !nBrowser.IsBusy && 
                  nBrowser.ReadyState == WebBrowserReadyState.Complete; }
        }
        public BrowsingUrl(System.Windows.Forms.Form theFormLayout)
        {

            this.nBrowser = new System.Windows.Forms.WebBrowser();
            this.nBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
            this.nBrowser.Location = new System.Drawing.Point(0, 0);
            this.nBrowser.MinimumSize = new System.Drawing.Size(20, 20);
            this.nBrowser.Name = "webBrowser1";
            this.nBrowser.ScrollBarsEnabled = false;
            this.nBrowser.Size = new System.Drawing.Size(1300, 700);
            this.nBrowser.TabIndex = 0;
            this.theFormLayout1 = theFormLayout;
            this.theFormLayout1.Controls.Add(this.nBrowser);
            this.nBrowser.ScriptErrorsSuppressed = true;
            this.nBrowser.Navigate("https://stackoverflow.com");
            this.nBrowser.DocumentCompleted += new System.Windows.Forms.WebBrowserDocumentCompletedEventHandler(this.nBrowser_DocumentCompleted);
        }
        private void nBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            //check for frames
            if (e.Url.AbsolutePath != (sender as WebBrowser).Url.AbsolutePath)
                return;

            // do stuff
            //Sample do stuff
            Thread.Sleep(10000);
            // end do stuff

            _isLoaded = true;
        }
    }  

And then you can wait until BrowsingUrl1 is loaded:

        BrowsingUrl BrowsingUrl1 = new BrowsingUrl(this);
        //Wait for the first page to load
        while (!BrowsingUrl1.IsLoaded)
        {
            Application.DoEvents();
        }
        BrowsingUrl BrowsingUrl2 = new BrowsingUrl(this);
Vojtěch Dohnal
  • 7,867
  • 3
  • 43
  • 105
  • thank you sir for your response , i tried this solution with no luck both instance are running , but this solution made it clear for me that the two instance are running in two separate thread , – magicalll Sep 28 '14 at 16:36
  • Yes I see it now, it does not work for some pages. The problem is that there is javascript executing within the page asynchronously. I will try to find some other way. – Vojtěch Dohnal Sep 28 '14 at 17:01
  • @magicalll Updated answer, tested and seems to work ok. But perhaps your problem might be that you want to access some HTML within the loaded document (the `do stuff`) and you want to get to that modifed HTML. That would be a different question. – Vojtěch Dohnal Sep 28 '14 at 18:18
  • yes you're absolutely right , the problem as you mentioned appears if i try to "do stuff" inside the nBrowser_DocumentCompleted otherwise the solution is perfect , but if i may ask you one last question , what approach would you recommend to manipulate the dom – magicalll Sep 28 '14 at 19:35
  • @magicalll I use Selenium Web Driver http://docs.seleniumhq.org/projects/webdriver/, or you may chack http://watin.org/. Those are tool used to unit test web pages (even containing AJAX etc.) – Vojtěch Dohnal Sep 29 '14 at 05:29
  • Also check http://stackoverflow.com/questions/2755747/how-to-use-watin-with-webbrowser-control – Vojtěch Dohnal Sep 29 '14 at 05:42