So as I'm looking over my socket server solution in Task Manager, I notice that the application is creating and destroying Threads (9 to 10 to 15 back to 10). Some of these could be used by the MySQL Connector, but it seems that logging into the server will create a new thread.
I'm using asynchronous sockets to accept a connection, pass it to the PacketHandler instance, allthewhile listening for simultaneous connections. My question is, how do I tell what code will create a new thread? I never explicitly wrote that a thread needed to be created, but it seems to be a consequence of using asynchronous sockets. I know you're supposed to be conservative when creating threads (Cores * 2 = target # of threads) but its a hard task when you don't know what code will create a new thread by nature.
Properly asynchronous code only uses threads for callbacks, which usually only needs thread-pool threads, and unless you're doing something wrong, there's no need to spin up new thread-pool threads.
This is certainly the case with the current implementation of Sockets in MS.NET. They register a callback on an asynchronous event, and a threadpool thread is used for the duration of that callback. Unless you're doing synchronous I/O operations in the callback, there's no point in creating any more threads on the threadpool.
Don't look in the task manager - look in the debugger. It might very well be that the threads you are seeing have nothing to do with the library you're using. There's quite a few infrastructure threads in .NET that are created and disposed of - notably, the garbage collector. Check the stack traces on those threads, and you'll know what they do.
EDIT: And in this case, it seems that the MySQL Connector indeed doesn't use asynchronous I/O. It's only pretending a synchronous I/O to be asynchronous using multi-threading - in other words, the asynchronous API is completely useless bollocks :) And since they are using threadpool threads for synchronous I/O, you're going to get plenty of problems with that. Either use a different library, or avoid the asynchronous API - it's lying to you.