ofiras said:
Well, I didn't really meant that all of my code would be in the same
function. This function would call other function.
You still have the complication of synchronization and coordination.
Refactoring code into multiple methods is the least of your worries.
I've tried doing it by navigating, adding DocumentCompleate event, and
when the event fires it calls another function that dose what it needs
to do. This is easy when it happens once, but I have to do several
things, and this makes it all messy. This way I have a lot of
functions and events, and it is hard to see the connections between
them.
Your code should not have "connections between them". That's the point
of encapsulation. So that one section of code can do its job without
worrying about what's going on in a separate section. Coordination
should happen only in specific, narrow bottlenecks, specifically so that
the connections between objects are kept simple and manageable.
If I could make a function that navigates to a certain url, waits
until loading is complete and only then returns, I could use for all
of my needs, and I believe it would be much simpler.
Unfortunately, that's just not how it would work out. Such a function
would introduce an unnecessary dependency between pieces of code that
really shouldn't need to depend on each other, would interfere with the
normal flow of execution in your main GUI thread, and will be overly
complicated to implement on top of all that (assuming you can get it to
work at all, which is not a foregone conclusion, given the WebBrowser
control's own ties to the main GUI thread).
This is how it should look:
private void Navigate_To_Url(string url)
{
webBrowser1.Navigate(url);
// Here is where the waiting for the DocumentCompleate
event would be
return;
}
Since using:
while (webBrowser1.ReadyState != WebBrowserReadyState.Complete ) ;
would stop the webBrowser from loading, i guess I have to use
threading.
_Anything_ that blocks that main GUI thread will have the same effect.
That's what I'm alluding to above. If you block that main GUI thread,
then window messages involved in the normal processing of things simply
don't get handled, causing the UI to just come to a halt.
If there is a way doing it, I would be thankful if you can write as
code (I understand it better since english, as you might have noticed,
is not my mother tongue).
Sorry if I haven't understood it correctly, and I really rather use
events and functions. I am not a professional, but still it looks to
me pretty obvious that waiting for the event would be better.
It's unfortunate that seems obvious to you, because all that means is
that your intuition is flawed.
Here's a short snippet that hopefully illustrates how your code really
should look:
class Form1 : Form
{
public Form1()
{
InitializeComponent();
// This could also be configured in the Designer,
// so that the InitializeComponent() method handles
// the initialization instead
webBrowser1.DocumentCompleted +=
webBrowser1_DocumentCompleted;
}
private void Navigate_To_Url(string url)
{
webBrowser1.Navigate(url);
}
private void webBrowser1_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
// do your processing here
}
}
If you have specific per-document state you need to deal with, then of
course you have to manage that. But anything that would properly avoid
blocking the main GUI thread would result in exactly that same issue
anyway. The most common approach is to simply disable the UI that would
allow the user to initiate another URL navigation, while the current
navigation is taking place, to ensure that only one can take place at a
time. But if you feel you need it, there are techniques you could use
to allow multiple navigations to take place simultaneously (assuming you
have multiple instances of the WebBrowser control in which each
navigation can take place, of course).
Pete