I have a networked server that I switched to using synchronous Begin.. for handling short lived request, this was a huge improvement. For the long lived ones two threads are created and with the increasing number of clients it is starting to become a problem.
The data transferred over these connections are messages of 4 to 40 bytes. However they are not length-delimited and their length can depend on parts inside their message. And sadly I can't change the protocol. You can think of the protocol as a fast paced telnet terminal protocol.
I'm looking into reading and parsing the incoming messages/"lines" using Stream.BeginRead and have reached two worries:
- Is it efficient to call BeginRead about 3 times for a 10 byte message?
- How do I efficiently write the code doing this
Here is one example. Although the message itself is not length prefixed some of it's content may be.
Synchronous method(current)
int length = reader.ReadInt32();
byte[] buffer = reader.ReadBytes(length);
Asynchronous method
...
//Here we have received a byte array
int length = ParseIntegerFromBuffer(buffer);
stream.BeginRead(buffer, 0, length, Part1Read, null);
}
private void Part1Read(IAsyncResult result)
{
...
The async example is not what I'm using, I've already written a few wrappers that take care of checking for successful read of the number of bytes requested. Is this as efficient in terms of writing and understanding the written code I can get?
My code must run on .NET 3.5 but in the future 5 is and option so should I wait for it and do the async programming then?
This code will face the internet and any hanging incoming connection would lock up a thread-pool thread if I used sync read.
I completed the asynchronous implementation and the result was 4 times higher CPU load than a design with one thread per connection.
The protocol being parsed is badly designed in itself and trying to parse it asynchronously did not help managing more connections.