This question is not about designs or patterns and which to use. The heart of this question is about what is happening regarding threads and blocking.
This example is to apply to any blocking method that is designed to perform the same action continuously. In this case it is a blocking read or write on a networkstream. Is there any appreciable difference behind the scenes as to threading and performance between the methods?
My assumption is that each of the methods below creates a thread or uses a pooled thread. Then blocks that thread until there is data to be read. Having said that and in that context, Is there any appreciable difference as to threading, performance and scalability between the methods?
Currently I am creating a server application. This application will have 1000 clients creating tcp connections. These connections will remain open, sending and receiving small amounts of data often. I am looking to use model A since it is the easiest to implement and the most maintainable. Will I end up with 1000 threads no matter which pattern is chosen?
Please note that these methods are just to give an idea of the structure and not something that would be used without proper streaming reads, timeouts, and exception handling.
Method A: Blocking
Task.Factory.StartNew(ReadMessage,TaskCreationOptions.LongRunning);
private void ReadMessage()
{
while(true)
{
TcpClient.Read();
}
}
Method B: Sleeping
Task.Factory.StartNew(ReadMessage,TaskCreationOptions.LongRunning);
private void ReadMessage()
{
while(true)
{
if(TcpClient.DataAvailable)
TcpClient.Read();
else
Thread.Sleep(1);
}
}
Method C: Recursive Begin/End
private void ReadMessage()
{
stream.BeginRead(readCallBack)
}
private void readCallBack()
{
stream.EndRead();
stream.BeginRead(readCallBack)
}
Method D: Async from BCL socket.ReceiveAsync()
private void readCallBack()
{
while(true)
{
await socket.ReceiveAsync(eventArgs);
}
}
Method E: Async method with blocking Read (Uses method D to call but is a custom method instead of using the built in exstendion of sockets from the BCL)
private async Task<byte[]> ReceiveAsync()
{
return await Task.Factory.StartNew(() => TcpClient.Read());
}