I look for the best practices to meet the following requirements:
I wonder whether the framework where I use BeginReceive
and EndReceive
with implemented IAsyncResult callback is state of the art given I target .Net 4.5. Is there a better solution, such as using NetworkStream or other API choices? What really bugs me with the BeginReceive/EndReceive implementation is that after EndReceive I have to call BeginReceive again and register the callback again. That sounds like an awful amount of overhead to me. Why can't new data be added async at any time and at the same time another context builds complete messages that are then routed through a raised event?
The argument of using IAsyncResult is often given in that thread handling is taken care of, but what speaks against the following: Using a NetworkStream and simply read from and write to the stream. As mentioned only string messages are exchanged and each message per protocol is marked complete by the line feed character. A separate task/thread would poll a streamreader (based on the networkstream) through ReadLine()
. It probably can`t get simpler than that, can it?
What I am basically asking is, how can the following code be made truly async?
public class SocketClient
{
private TcpClient client;
private StreamReader reader;
private StreamWriter writer;
public event Action<string> MessageCallback;
public SocketClient(string hostname, int port)
{
client = new TcpClient(hostname, port);
try
{
Stream stream = client.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
writer.AutoFlush = true;
//Start Listener on port
StartListener();
}
catch (Exception e)
{
throw new Exception(e.ToString());
}
}
public void StartListener()
{
Task task = Task.Factory.StartNew(() =>
{
while (true)
{
if (MessageCallback != null)
{
MessageCallback(reader.ReadLine());
}
//Thread.Sleep(200);
}
});
}
}
There is no current standard or common practice at the moment. You have a number of choices, each with advantages and disadvantages:
Task
s and use async
/await
.
async
operations yourself within an "infinite" loop as well as handle state management for each connection.*Async
methods into Task
s and use async
/await
.
For your situation (a few hundred messages per second on less than a hundred sockets), I would recommend using my Nito.Async library. It's the easiest one of these options to get working.
Regarding your protocol, you'll have to parse out the \n
s by hand and do your own buffering. (That's true for all the choices above).
As per my recommendation please use new Async form of XXXReceive
and 'XXXSend' (where XXX stands for Begin
and End
), the new methods available are ReceiveAsync and SendAsync methods which uses SocketAsyncEventArgs to pass the socket and other information on the callbacks event handlers.
I had seen a good working example of socket client and server on msdn archive which was scalable upto 500 connections (As I had tested in one of project adaptation from it) but currently I am not able to find that link from googling.. but here is another link from msdn archive on the same topic hopefully it will help you - Get Closer to the Wire with High-Performance Sockets in .NET..
First of all I can only provide you idea to final implementation and if possible some short example code snippets. ok here I go with more details
I think you can jump to last paragraph's link. ;)
Let me highlight once because I want to, I said SendAsync
and ReceiveAsync
not BeginReceive/EndReceive
and BeginSend/EndSend
i.e. Event-based Async Pattern (EAP)
Benefit of using Async form of Socket methods is that they are exception-less approach to socket programming which can prove faster than BeginSend/EndSend methods.
Here is the link for the sample which I have found to be useful upto 500 PARALLEL connections - Networking Samples for .NET v4.0
For you need to use await/async feature of .NET 4.5. Here is the .NET 4.5 code snippet showing usage of WebSocket
class which of can be adapted to Socket
implementations also - Support for WebSockets Protocol (I guess WebSocket's AspNetWebSocketContext
will be Socket's SocketAsyncEventArgs
)
I found Awaiting Socket Operations sample code from MSDN - Parallel Programming team blog which can be useful to use to implement await/async from .NET 4.5 framework.
I hope this proves helpful to you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With