我正在尝试从使用异步套接字代码(包含一些混乱的BeginSend
/EndSend
,BeginReceive
/EndReceive
以及许多内部"管理")转换到使用异步TcpClient。我对异步/等待非常新手,请多多包涵...
假设以下代码(已剥离无关代码):
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));
}
}
}
我的类有一个内部的stringbuilder,每次接收到数据时都会进行追加(这是因为消息可以在多个接收“事件”中被分割)。然后,在满足某些条件时,处理字符串生成器(“运行缓冲区”),将消息分割成消息的“部分”。对于每个“部分”,都会触发一个事件。系统中可以运行许多此类实例。
我的问题是:
- 我是否正确地认为/理解了
MyInternalStringBuilder.Append
从未“无序”调用?每次TcpListener
接收数据时,它将被“按顺序”添加到(内部)字符串构建器中?我不需要使用锁吗? - 由于此
StartReceive
方法使用一个内部的(“无限”)循环并引发事件,因此我不明白使 StartReceive 方法成为async
的意义,但是我必须这样做(显然可以使用await
)。我知道我正在混合 TAP/EAP,但出于与本问题无关的原因,我必须这样做。然而,感觉很“肮脏”,因为到目前为止我所了解的是“async
不应该是void
”。也许有更好的方法来解决这个问题(除了完全转向 TAP)?