0
votes

I am writing a server/client socket app in C# on Windows 10 platform. The server side code and GUI code are running in the same process. On the server side I am trying to optimize my code as I can have 255 socket client connections. I have followed Microsoft “Synchronous Server Socket Example”. I have moved (from their example) all the logic of “public static void ReadCallback(IAsyncResult ar)” to:

Task.Run(() =>
{
ReadCallback(IAsyncResult ar);
});

.. , hoping that “ReadCallback” will be called from a different thread, therefore releasing call-back socket thread ASAP. Is that going to create a problem since I have now call ‘socket.EndReceive(ar)’ and ‘socket.BeginReceive(…)’ called possibly from different thread? The code is still working but I don’t know whether it is by accident or by my design. Please comment on that.

1
IAsyncResult comes from APM, Task.Run is TPL, you shouldn't mix the two approaches. Task.Run will run on the thread pool, ReadCallback will probably run on different thread pool thread - Pavel Anikhouski
No, End/BeginReceive() was always called from a threadpool thread before Task/async was added. Using Task.Run does completely defeat the point of using BeginReceive(), which was to only use a thread and run code when there's something useful to do. Mixing is not a good idea. - Hans Passant
Thanks Gents for the reply. So the general rule is to use APM thread pool and live TPL alone. Do I understand that correct? - Rejkid

1 Answers

0
votes

According to .Net documentation all Socket calls are threadsafe.

Thread Safety

Instances of this class are thread safe.

I have written other code with Begin.. and End.. in different threads. However in hindsight it wasn't the best way to do it.

I would suggest a Task per TcpClient connection, handling the in and the out, if you really don't need and synchronization between the In and Out then that Task could spawn a In Task and an Out Task but still be under the control of the TcpClient Task.

For high performance IO, I would suggest checking out System.IO.Pipelines