Hello, any help here would be much appreciated.
In my program the client application connects to the server application over the internet. This works fine when I have the server application running. But if I turn the server application off (to simulate the server being down) the client application freezes while it waits for the server to time out. I am talking freezing. In windows Vista I get the (Not Responding) message in the title bar. But then once the server times out, my client application carries on just as I have programmed it to.
Also, I want to display a progress bar (in marquee style) while the client is waiting on the server.But for some reason, even though I call the code to run the progress bar before I call the code to connect to the server, the progress bar actually disappears from my form! However, it does return again once the server has timed out and control is returned to my program.
Here are the snippets of code involved in making this happen:
First the button event handler is called:
private void btnLogin_Click(object sender, EventArgs e)
{
// Make sure username and password fields are not blank
if (TestForEmptyLoginBoxes() == true)
return;
// If existing user...
if (cbNewUser.Checked == false)
Login();
else // If new user...
CreateUser();
}
Then that calls the Login() method. This method is longerbut I am only showing the code relevant to my question:
private void Login()
{
string username = txtUserName.Text;
string password = txtPassword.Text;
bool connected = false;
// Connect
try
{
StartProgressBar("Connecting");
connected = Connect();
}
catch (Exception e)
{
SetDisplay_lblError(e.Message);
StopProgressBar();
}
}
First Login() starts the progress bar(or is supposed to start the progres bar) by calling StartProgressBar():
private void StartProgressBar(string progressLabel)
{
progressBar.Style = ProgressBarStyle.Marquee;
progressBar.MarqueeAnimationSpeed = 40;
UpdateProgressBar(progressLabel);
}
StartProgressBar() then calls UpdateProgressBar which just changes the size of the progress bar and its corrosponding descriptive label.I know doing it that way is a little unusual but that's the way I chose to do it. Anyway, this is UpdateProgressBar():
private void UpdateProgressBar(string progressLabel)
{
// Setup varibales
Graphics g = this.CreateGraphics();
Point pBarLoc = progressBar.Location;
string newProgressString = progressLabel;
SizeF oldLabel = g.MeasureString(lblProgress.Text, lblProgress.Font);
SizeF newLabel = g.MeasureString(newProgressString, lblProgress.Font);
int lblDif = (int)(newLabel.Width - oldLabel.Width);
Rectangle changeRect = new Rectangle();
// Chane the text box and progres bar
lblProgress.Text = newProgressString;
progressBar.Location = new Point(pBarLoc.X + lblDif, pBarLoc.Y);
progressBar.Width -= lblDif;
// Invalidate the controls so they are redrawn
changeRect.Location = lblProgress.Location;
changeRect.Height = progressBar.Height;
changeRect.Width = (progressBar.Location.X + progressBar.Width) - lblProgress.Location.X;
Invalidate(changeRect);
}
After UpdateProgressBar() completes control is returned to StartProgressBar() which then completes and controls is returned to Login(). Login then calls Connect(). It should be noted that if I comment out the call to Connect(), everything works perfectly. But when comment runs the client application freezes for a while (which causes Vista to think my program has frozen) and then unfreezes once it's attempt to connect to the server times out. Here is the Connect() method:
private bool Connect()
{
if (ChannelServices.GetChannel("chatAppChannel") == null)
network = new Network();
network.Connect();
return true;
}
Then Connnect() method creates a Network object. (I wrote the Network class myself, it's not from Microsoft). The Network constructor just registers the channel that will be used forremoting:
public Network()
{
try
{
chatAppChannel = new TcpChannel();
ChannelServices.RegisterChannel(chatAppChannel, false);
}
catch (Exception e)
{ throw new Exception("Remoting Error: unable to instantiate or register channel " + e.Message); }
}
After the Network object has been created, network.Connect() is called:
public void Connect()
{
try
{
string serverAddress = Dns.GetHostEntry("www.myAddress.info").AddressList.ElementAt(0).ToString();
serverObject = (ChatAppInterface.clientServerInterface)Activator.GetObject(typeof(ChatAppInterface.clientServerInterface), "tcp://" + serverAddress + ":1212/ServerObject");
serverObject.ToString(); // test to see if the remote object is working
}
catch (Exception e)
{
string detail = e.Message;
throw (new Exception("Error creating remote object. Details: " + detail));
}
}
As you can see, the way I am having my client find the server across the internet is to resolve a domain name into an ip address. That is not my actual domain name. It has been changed to
www.myAddress.info for anonymity. Anyway this method does work when I have the server running and I am able to create and use the remot object. I believe it is here where the program ends up freezing while it tries creating the remote object on the server. Again, the reason it is unable to create the remote object is because I am not running the server application (for testing purposes). So it times out because of that but I imagine the client application would also freeze if the user had a very slow internet connection.
Anyway, after this method throws it's exception, control is returned to Login() which displaysan error message on the form. Then you can try to log in again and go through the same thing all over again. The program doesn't crash, it just freezes and for some reason turns the progress bar inivisible even though I don't specify anywhere for the progress bar to turn invisible.
So to sum up my question. How do I stop my appliction from freezing while it is trying to connect to a server on the internet? Also, why is my progress bar dissapearing??? If I use a thread somewhere will that help me?
Thanks for your help