Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Force method to wait until variable has a value

Posted on 2008-10-06
17
Medium Priority
?
5,057 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Learn Veeam advantages over legacy backup

Every day, more and more legacy backup customers switch to Veeam. Technologies designed for the client-server era cannot restore any IT service running in the hybrid cloud within seconds. Learn top Veeam advantages over legacy backup and get Veeam for the price of your renewal

 
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
 
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…

670 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