First of all, thank You for reading this post and wish You best in 2021 :)
My scenario: I have TCP server on computer 1, and multiple TCP clients connected to it (which is working fine). This is implemented via SuperSimpleTCP nuget-package.
Currently: Clients are trying to reconnect but UI is blocked, when TCPServer is back online TCPClient will connect and UI is not blocked anymore.
Expected result: After disconnect or connection error client should try to reconnect every 5 seconds until connection is established without blocking UI.
In FormTCPClient_Load i have following :
private void FormTCPClient_Load(object sender, EventArgs e)
{
string TCPIP = ConfigurationManager.AppSettings["TCPServerIP"];
client = new SimpleTcpClient(TCPIP);
client.Events.Connected += Events_Connected;
client.Events.DataReceived += Events_DataReceived;
client.Events.Disconnected += Events_Disconnected;
//ConnectToTCP();
LaunchTaskAsync();
}
LaunchTaskAsync() looks like this :
void LaunchTaskAsync()
{
if (client.IsConnected) { StopTask(); return; }
taskToken = new CancellationTokenSource();
Task.Factory.StartNew(() =>
{
try
{ //Capture the thread
runningTaskThread = Thread.CurrentThread;
// Run the task
ConnectToTCP();
if (taskToken.IsCancellationRequested || !awaitReplyOnRequestEvent.WaitOne(50000))
return;
//Console.WriteLine("Task finished!");
}
catch (Exception exc)
{
MessageBox.Show(exc.ToString());// Handle exception
}
}, taskToken.Token);
}
Stop Asycn looks like this:
void StopTask()
{
// Attempt to cancel the task politely
if (taskToken != null)
{
if (taskToken.IsCancellationRequested)
return;
else
taskToken.Cancel();
}
// Notify a waiting thread that an event has occurred
if (awaitReplyOnRequestEvent != null)
awaitReplyOnRequestEvent.Set();
// If 1 sec later the task is still running, kill it cruelly
if (runningTaskThread != null)
{
try
{
runningTaskThread.Join(TimeSpan.FromSeconds(1));
}
catch (Exception ex)
{
runningTaskThread.Abort();
}
}
}
ConnectToTCP() looks like this :
private void ConnectToTCP()
{
this.Invoke((MethodInvoker)delegate
{
try
{
client.Connect();
this.BackColor = SystemColors.Control;
this.Invalidate();
}
catch (Exception ex)
{
this.BackColor = Color.Red;
this.Invalidate();
StopTask();
LaunchTaskAsync();
}
});
}
Disconnect event :
private void Events_Disconnected(object sender, ClientDisconnectedEventArgs e)
{
this.Invoke((MethodInvoker)delegate
{
try
{
this.BackColor = Color.Red;
this.Invalidate();
LaunchTaskAsync();
}
catch (Exception ex)
{
this.BackColor = Color.Red;
this.Invalidate();
}
});
}
Connect Event:
private void Events_Connected(object sender, ClientConnectedEventArgs e)
{
this.Invoke((MethodInvoker)delegate
{
try
{
StopTask();
this.BackColor = SystemColors.Control;
this.Invalidate();
}
catch (Exception ex)
{
this.BackColor = Color.Red;
this.Invalidate();
}
});
}