Dimi Dimi - 1 month ago 11
C# Question

ThreadPool behavior and TCPListener

I am starting

TCPListener
like this and when the job done I close the
Socket
.
I would like to know if the
Thread
which I start like this

ThreadPool.QueueUserWorkItem(ConnectClientsThredProc, args);


is going to destroy itself so I don't need any external control over it.

Would anyone so pleased to explain have I worry about it or don't.
Thank you!

class TCPListenerManager
{
TcpListener tcpListener;
HostListenerItem hostListener;
private bool _isServerWorking = false;

public TCPListenerManager(HostListenerItem hostListenerItem)
{
hostListener = hostListenerItem;

tcpListener = new TcpListener(IPAddress.Parse(hostListenerItem.IP4), hostListenerItem.Port);

var t = Task.Factory.StartNew(async () =>
{
await StartAsync(hostListenerItem.ClientsMax);
});
}

public async Task StartAsync(int clientsMax)
{
tcpListener.Start();
_isServerWorking = true;
for (int i = 0; i < clientsMax; i++)
{
if (_isServerWorking)
{
ServerConnectedEventArgs args = new ServerConnectedEventArgs();
args.TcpClient = await tcpListener.AcceptTcpClientAsync();
args.HostListener = hostListener;

OnServerConnected(args);
ThreadPool.QueueUserWorkItem(ConnectClientsThredProc, args);
}
}
}


private void ConnectClientsThredProc(object obj)
{
var args = (ServerConnectedEventArgs)obj;

if (args.TcpClient.Connected)
{
// Do some job and disconnect
args.TcpClient.Client.Close();
args.TcpClient.Client = null;
}
}
}

Evk Evk
Answer

When ConnectClientsThredProc exits, thread is not "gone" but returned back to the pool (that's why thread pool exists in the first place). Anyway, you should not care about that indeed, unless you have long-running task performed in ConnectClientsThredProc. If it is long running - better not use thread pool thread, but start a new one (via Task.Factory.StartNew + TaskCreationOptions.LongRunning for example).

Also, you use Task.Factory, async\await, ThreadPool.QueueUserWorkItem, all that in a short piece of code, mixed together. Maybe you need to understand a bit better what are those tools and what are similarities and differences between them (especially async\await). For example, what is the reason for this:

var t = Task.Factory.StartNew(async () =>
{
      await StartAsync(hostListenerItem.ClientsMax);
 });     

You start a task\thread, inside which you start yet another task and then wait for it to exit - makes little sense.

Instead of ThreadPool.QueueUserWorkItem you might use Task.Run with the same effect.

Comments