Reputation: 389
I have been reading about Threadpool.QueueUserWorkItem
(what I've been using), Task.Run
and Task.Factory.StartNew
and am still unclear as to what the right option is here. It seems since my work is not CPU bound, I should probably not use Task.Run
I have my own thread running that waits for connections:
Thread listenThread = new Thread(() => ListenForConnection());
listenThread.Name = "lThread";
listenThread.IsBackground = true;
listenThread.Start();
and inside that I am simply doing:
tlist = new TcpListener(IPAddress.Parse(ip.ToString()), 27275);
tlist.Start();
while (isRunning) {
try {
var client = await tlist.AcceptTcpClientAsync();
ThreadPool.QueueUserWorkItem(HandleClient, client);
}
catch (Exception) { }
}
HandleClient
parses the message the client sends, and either creates an instance of a simple class or updates an existing one if the client already exists, stores references to the connection, and also updates a few UI elements.
Is ThreadPool.QueueUserWorkItem
the preferred method here or am I way off?
Edit: just to note, the HandleClient
function usually takes between 5 and 30 ms, so not very heavy work
Upvotes: 1
Views: 37
Reputation: 171226
QueueUserWorkItem
, StartNew
and Run
are more or less equivalent. I'd pick Task.Run
because it is the most modern way to do it.
The way you have done it is totally OK. You have chosen a synchronous HandleClient
implementation which forces you to handle the connection on a separate thread. Note, that this can consume many resources in case of many concurrent connections. If you are not interested in that scenario this is not a problem. Otherwise, it is a dealbreaker.
In case you make HandleClient
truly asynchronous and non-blocking you do not need to push that call onto the thread-pool. My advice is to still do that because it has very little downside and it protects you against an overly long synchronous initial part of that method.
catch (Exception) { }
this I don't understand. This might hide bugs. Also, if there is an error accepting most likely it is a permanent error. This kind of error handling will turn the loop into a busy loop consuming 100% of one CPU code. Move the catch outside of the loop.
Upvotes: 1
Reputation:
I would say like this:
var tcpListener = new TcpListener(IPAddress.Any, 80);
tcpListener.Start();
while (true)
{
var tcpClient = tcpListener.AcceptTcpClient();
Task.Factory.StartNew(() =>
{
// Do whatever you like with your TcpClient
});
}
Upvotes: 0