Reputation: 155
When setting up my socket for connecting, I wrap the method in a try-catch block..
If a socket exception gets raised, I create a new thread.. sleep for 15 seconds.. and then call the connect method again but this time from another thread. I'm doing this mainly for the sleep method (to avoid using a timer to reconnect) to not hang up the main thread.
Anyhow.. when trying to connect, I write the status to a text box using a method called Write() which just appends the text to the current text with a \n before it...
Because on a failed connect I create a separate thread to call the connect method (which DOES modify a control on the form), I am right to use invoke on the method call right?
Here is my code
private void Connect()
{
try
{
Write("Connecting...");
_ClientSocket.Connect(new IPEndPoint(IPAddress.Loopback, 2500));
Connected = true;
Write("Connected.");
_ClientSocket.BeginReceive(Buffer, 0, Buffer.Length, 0, new AsyncCallback(RecieveCallBack), null);
}
catch (SocketException ex)
{
Write("Connection Failed. Trying again in 15 Seconds...");
Connected = false;
new Thread(delegate()
{
Thread.Sleep(15000);
Invoke((MethodInvoker)delegate
{
this.Connect();
});
}).Start();
}
catch (Exception ex)
{
}
}
I just want to be sure I am doing this in the proper way
Upvotes: 0
Views: 1085
Reputation: 22008
Instead of creating thread to connect you could initially assume, what your connect will not be successful. This will required to have polling timer to reconnect. Bonuses: you can control timer (while you can do nothing with anonymous thread), you can use it for other tasks required polling (resend data, which was not delivered at first try, queue connect after disconnect if you change socket settings, etc).
This polling timer can be a normal UI timer (Timer in case of winforms), then you don't need any invoke. If you go this way, then make sure don't have blocking operations in it (to example, sending data and waiting for an answer).
Otherwise, you can use this extension method for methods to always run them in UI thread
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
if (control.InvokeRequired)
control.Invoke(action);
else
action();
}
In your case you will want to call Write
like this
someUIControl.InvokeIfRequired(() => Write(...));
Or simply make Write
method like this
void Write(...)
{
if(someUIControl.InvokeRequired)
someUIControl.Invoke((delegate)() => Write(...));
else
{
... job here
}
}
Upvotes: 1
Reputation: 1063994
In the scenario presented, it is using new Thread
, Thread.Sleep
and Invoke
simply as a way of schedule some work to happen on the UI thread in 15 seconds. It'll work, but... pretty inefficient (threads are expensive). Frankly, a timer should be used instead - or perhaps Task.Delay
on 4.5 (which actually just wraps a timer anyway).
Upvotes: 1