I'm creating a server that a TCP connection. The TCP Connection is run in its own thread for an indefinite amount of time. Is there a good pattern to allow safe shutdown of the TcpListener and Client as well as the thread? Below is what I have so far.
private volatile bool Shudown;
void ThreadStart1()
{
TcpListener listener = null;
TcpClient client = null;
Stream s = null;
try
{
listener = new TcpListener(60000);
client = listener.AcceptTcpClient();
Stream s = client.GetStrea();
while(!Shutdown) // use shutdown to gracefully shutdown thread.
{
try
{
string msg = s.ReadLine(); // This blocks the thread so setting shutdown = true will never occur unless a client sends a message.
DoSomething(msg);
}
catch(IOException ex){ } // I would like to avoid using Exceptions for flow control
catch(Exception ex) { throw; }
}
}
catch(Exception ex)
{
LogException(ex);
throw ex;
}
finally
{
if(listener != null) listener.Close();
if(s != null) s.Close();
if(client != null) client.Close();
}
}
If the thread that calls Abort holds a lock that the aborted thread requires, a deadlock can occur. If Abort is called on a thread that has not been started, the thread will abort when Start is called. If Abort is called on a thread that is blocked or is sleeping, the thread is interrupted and then aborted.
A blocked thread can be interrupted by calling the interrupt() method of Thread class. This interrupt is a pure Java mechanism and is neither CPU nor operating system level interrupt. The interrupt() method does not interrupt a running thread i.e. thread which is in RUNNABLE state.
The running thread will block when it must wait for some event to occur (response to an IPC request, wait on a mutex, etc.). The blocked thread is removed from the running array, and the highest-priority ready thread that's at the head of its priority's queue is then allowed to run.
Set a timeout on the NetworkStream (client.ReadTimeout=...). Once the read operation times out, check to see if the main thread signalled you to stop (by setting a variable or an AutoResetEvent). If it's been signalled to stop, exit gracefully. If not, try reading again until the next timeout.
Setting a 0.5 or 1 second timeout should suffice - you will be able to exit the thread in a timely manner, and yet be very easy on the CPU.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With