Solved

Force method to wait until variable has a value

Posted on 2008-10-06
17
4,847 Views
Last Modified: 2013-12-17
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";
}


0
Comment
Question by:GaryRasmussen
  • 10
  • 3
  • 2
  • +2
17 Comments
 
LVL 26

Expert Comment

by:Anurag Thakur
ID: 22655453
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22655469
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22655506
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
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 22655529
why not just do what you want at DocumentComplete method ?
0
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22655552
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22655638
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
 
LVL 16

Expert Comment

by:CuteBug
ID: 22655660
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22655755
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 16

Expert Comment

by:CuteBug
ID: 22656294
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22657024
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
 
LVL 13

Expert Comment

by:joechina
ID: 22660205
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22661293
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
 
LVL 1

Accepted Solution

by:
GaryRasmussen earned 0 total points
ID: 22661634
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
 
LVL 13

Expert Comment

by:joechina
ID: 22661696
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
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22661760
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
 
LVL 13

Expert Comment

by:joechina
ID: 22662370
I had not seen your post before I posted my last one.
Your solution is fine but takes a little more CPU resourse.
0
 
LVL 1

Author Comment

by:GaryRasmussen
ID: 22662619
ok great and thanks to all of you who took the time to try and help me.
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

This document covers how to connect to SQL Server and browse its contents.  It is meant for those new to Visual Studio and/or working with Microsoft SQL Server.  It is not a guide to building SQL Server database connections in your code.  This is mo…
Today I had a very interesting conundrum that had to get solved quickly. Needless to say, it wasn't resolved quickly because when we needed it we were very rushed, but as soon as the conference call was over and I took a step back I saw the correct …
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now