【发布时间】:2013-12-17 23:38:07
【问题描述】:
我正在尝试从有点混乱的异步套接字代码(BeginSend/EndSend、BeginReceive/EndReceive 和大量内部“管理”)转移到异步TcpClient。我对 async/await 还很陌生,所以请多多包涵……
假设以下代码(不相关的代码被剥离):
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));
}
}
}
我的班级有一个内部字符串生成器,每次接收到数据时都会附加到该字符串生成器(这是因为消息可以拆分为多个接收“事件”)。然后,当满足某些条件时,处理字符串生成器(“运行缓冲区”)并将消息拆分为消息“部分”。对于每个“部分”,都会引发一个事件。该类的许多实例可以在系统中运行。
我的问题是:
- 我是否正确假设/理解
MyInternalStringBuilder.Append从未被称为“故障”?每次TcpListener收到数据时,它都会“按顺序”添加到(内部)字符串构建器?我不需要使用锁? - 由于这个
StartReceive方法使用内部(“无限”)循环并引发事件,我看不出创建StartReceive 方法async的意义,但我必须(因为显然能够使用@987654332 @ 完全没有)。我知道我正在混合 TAP/EAP,但出于与此问题无关的原因,我必须这样做。但是,感觉“脏”,因为“async不应该是void”是我迄今为止收集到的。也许有更好的方法来解决这个问题(除了一起迁移到 TAP)?
【问题讨论】:
-
我建议从 channel9 观看 Async in ASP.NET,它还介绍了 C# 中使用 AMP、EAP 和 TAP 的异步的简史。可能对你有帮助
-
我会(我一回到家,因为我这里没有音频),但我应该指出这段代码是作为(“系统”)服务运行的,而不是在 IIS 中并且什么都没有与 ASP.NET 相关(虽然我不确定视频是否专门针对此,但...)
-
它专门针对 ASP.NET,但关于异步的一般概念是相同的,我相信它无论如何都会为您提供一些价值。
标签: c# async-await tcpclient