I'm trying to move from async socket code which is a bit messy (BeginSend/EndSend, BeginReceive/EndReceive and lots of internal 'administration') to an async TcpClient. I'm pretty new to async/await, so please bear with me...
Assume the following code (irrelevant code stripped):
public async void StartReceive()
{
while (true)
{
var stream = this.MyInternalTcpClient.GetStream();
if (stream == null) return;
var buffer = new byte[BUFFERSIZE];
var bytesread = await stream.ReadAsync(buffer, 0, BUFFERSIZE);
if (bytesread == 0)
{
if (Closed != null)
Closed(this, new ClosedEventArgs());
return;
}
var message = this.Encoding.GetString(buffer, 0, bytesread);
this.MyInternalStringBuilder.Append(message);
// ... message processing here ...
foreach (var p in parts) {
//Raise event per message-"part"
if (MessageReceived != null)
MessageReceived(this, new MessageReceivedEventArgs(p));
}
}
}
My class has an internal stringbuilder that gets appended to each time data is received (this is because messages can be split up in more than one receive 'event'). Then, when some conditions are met, the stringbuilder (the "running buffer") is processed and the message is split into message-"parts". For each "part" an event is raised. Many instances of this class can be running in the system.
My questions are:
- Am I correct in assuming/understanding the
MyInternalStringBuilder.Appendis never called "out of order"? Each time theTcpListenerreceives data it will be added, "in order", to the (internal) stringbuilder? I don't need to use locks? - Since this
StartReceivemethod uses an internal ("infinite") loop and raises events I don't see the point in making the StartReceive methodasync, but I have to (for obviously being able to useawaitat all). I know I'm mixing TAP/EAP but I have to for reasons not relevant to this question. However, it feels "dirty" since "asyncshouldn't bevoid" is what I gathered so far. Maybe there's a better way to solve this (except for moving to TAP alltogether)?