Force method to wait until variable has a value

I have a windows form that is using the web browswer control.  I have a method that opens a page in the web browser control.  When the web browser control is finished loading the page, it looks for and saves a value found in the html of the loaded page.  My method that navigates the web browser control needs to wait until the value is found before it can do anything.  I tried accomplishing this several ways.  One way was to pause the thread but that stops everything, including the web browser control so that it never finishes loading the page and thus never finds and saves my value.  See example ...

string myValue = null;

private void GoToPage()
{          webBrowser.Navigate("http://page.htm", ref empty, ref empty, ref empty, ref empty);
            while (myValue == null)
            {       System.Threading.Thread.Sleep(1000); //the value has not been found yet
            }
            MessageBox.Show(myValue);
}

private void webBrowser_DocumentComplete(n/a)
{            myValue = "example";
}


LVL 1
GaryRasmussenAsked:
Who is Participating?
 
GaryRasmussenConnect With a Mentor Author Commented:
I solved this one on my own.  Thanks to everyone that tried to help.  I will add my solution here for some other poor sap like me :)


bool pageLoaded = false;
 
private void GoToPage()
{	webBrowser.Navigate("http://page.htm");
	do
	{	System.Windows.Forms.Application.DoEvents();
	}
	while(! pageLoaded);
	
	myValue = "example";
	pageLoaded = false;
}
 
private void webBrowser_DocumentComplete(n/a)
{	myValue = "example";
	pageLoaded = true;
}

Open in new window

0
 
Anurag ThakurTechnical ManagerCommented:
dont use the threading.sleep because your are asking your main processing thread to sleep
instead either user a timer which checks for the value after some time interval or use a while loop just to kill some time so that the value myValue is filled
0
 
GaryRasmussenAuthor Commented:
can you offer an example of how to use the timer control in my application?  I don't quite understand how it works.

Thanks!
0
The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

 
GaryRasmussenAuthor Commented:
This is so simple in javascript using setInterval and having the function just continue to call itself until the condition is met and then just return the value to the method that called the function.
0
 
Jaime OlivaresSoftware ArchitectCommented:
why not just do what you want at DocumentComplete method ?
0
 
GaryRasmussenAuthor Commented:
The method that loads the pape into the control will be opening a file and then looping several pages, saving the value found each time.

Get the page
Find the value
Save the value
Go to the next page
0
 
GaryRasmussenAuthor Commented:
This seems like it would work but it doesn't ...

do
{     //this is one way to wait but there ought to be a better way?
}
while(myValue == null);
                  
MessageBox.Show(myValue);
0
 
CuteBugCommented:
Use System.Threading.ManualResetEvent.


ManualResetEvent myManualEvent = new ManualResetEvent(false);
 
private void GoToPage()
{          webBrowser.Navigate("http://page.htm", ref empty, ref empty, ref empty, ref empty);
           myManualEvent.WaitOne(); 
           MessageBox.Show(myValue);
}
 
private void webBrowser_DocumentComplete(n/a)
{            myValue = "example";
             myManualEvent.Set();
}

Open in new window

0
 
GaryRasmussenAuthor Commented:
wow, when I see stuff like this I realize I don't know jack.  I have never heard of this.  Thank you!!

While this works, there is something very strange happening.  After I click the button to call the GoToPage method, nothing ever happens unless I click on the application tab in the task bar several times.  I would not have even noticed it but it seems like the ap freezes and I was trying to right-mouse click on the application tab so that I could close the application?  Almost like the ap lost focus or forgot that it was waiting for something.

If you click the button to call the GoToPage method, the browser never goes to the page.  Nothing happens and I waited for up to 3 minutes.  But as soon as you click the application tab several times, the browser goes to the web page and the message box pops up the value as it should.  A left mouse click will not do anything.  You have to right-mouse click the tab 3 times to make it work.  I know, wierd.  I have no other code in this form.
0
 
CuteBugCommented:
This is because of the Sleep method you are calling.

Once you use the ManualResetEvent and remove the Sleep method, it should work fine.
0
 
GaryRasmussenAuthor Commented:
I am not using the sleep method.  In fact, my code looks almost identical to your example.  I will attach my form (the cs and resx file in zip format).  There are only 2 small methods.

Thank you,
0
 
joechinaCommented:
Use System.Threading.ManualResetEvent would not help here because the document complete event is still run by the same thread as GoToPage().

Why not just move all the code behind
 webBrowser.Navigate("http://page.htm", ref empty, ref empty, ref empty, ref empty);

Into
Document complete event handler?
0
 
GaryRasmussenAuthor Commented:
Because there are several other things happening here that I left out so that we could stay focused on what the question is.  The web browser control is used for other functions before actually getting to this area where I need a wait mechanism like logging into a site and also selecting/submitting  parameters for building a download request.  Plus I have this chicken/egg thing going on ...

The method that loads the page into the control does so based on a looked up value.  So it gets say a ProductID from the first row of a file of 500 products...

- Use the ProductID to build the URL and go to that page ine the browser
- The page finishes loading
- A particular value is found on the page (this has to happen after the page  is fully loaded)
- The value is saved to the same row as the ProductID (would be nice if this could just be returned to the method that loaded the control with the web page so that the file read/write would be cleaner.

This waiting is a common problem and since I am new to Windows Forms, I am really suprised this one hasn't been solved yet.  I come from a web application background where a situation like this would be easily solved using a javascript function that recursively called itself with a setInterval until the value was scraped and then just returned it back to whatever called it.

And why doesn't a while loop work in this situation?  I swear I have tried every logical way to do this simple wait and none of them work correctly.  I thought this stupid application was going to take me an afternoon, not 3 days.  Geez
0
 
joechinaCommented:
Ok, in this case, your GoToPage() should run in a different thread.

So, use the code provided by cutebug,  change the code where you call GoToPage() to
(new Thread(new ThreadStart(GoToPage))).Start();
0
 
GaryRasmussenAuthor Commented:
Is there a reason I should change it since it is working now?  With the solution I posted, I don't need to keep a public variable, I can just keep it all inside the GoToPage.

Thanks!
0
 
joechinaCommented:
I had not seen your post before I posted my last one.
Your solution is fine but takes a little more CPU resourse.
0
 
GaryRasmussenAuthor Commented:
ok great and thanks to all of you who took the time to try and help me.
0
All Courses

From novice to tech pro — start learning today.