我寻找满足以下要求的最佳做法:
我想知道我使用BeginReceive
和EndReceive
实现IAsyncResult回调的框架是否是最先进的,因为我的目标是.Net 4.5。有没有更好的解决方案,例如使用NetworkStream或其他API选择?使用BeginReceive / EndReceive实现真正让我感到困惑的是,在EndReceive之后,我必须再次调用BeginReceive并再次注册回调。这对我来说听起来像是一个可怕的开销。为什么新的数据不能随时添加异步,同时另一个上下文构建完整的消息,然后通过引发的事件进行路由?
使用IAsyncResult的论点通常是在处理线程处理时给出的,但是反对以下内容:使用NetworkStream并简单地读取和写入流。如上所述,只交换字符串消息,每个协议的每条消息都由换行符标记完成。单独的任务/线程将通过ReadLine()
轮询流读取器(基于网络流)。它可能不会比那简单,是吗?
我基本上要问的是,以下代码如何才能真正实现异步?
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);
}
});
}
}
答案 0 :(得分:13)
目前没有现行的标准或惯例。你有很多选择,每个选择都有优点和缺点:
Task
并使用async
/ await
。
async
操作,并处理每个连接的状态管理。*Async
methods加入Task
并使用async
/ await
。
根据您的情况(少于一百个套接字,每秒几百条消息),我建议使用我的Nito.Async库。这是最容易使用的选项之一。
关于您的协议,您必须手动解析\n
并进行自己的缓冲。 (对于上述所有选择都是如此)。
答案 1 :(得分:1)
根据我的建议,请使用XXXReceive
和'XXXSend'的新异步表单(其中XXX代表Begin
和End
),可用的新方法为ReceiveAsync和SendAsync方法,它们使用SocketAsyncEventArgs来传递回调事件处理程序上的套接字和其他信息。
我在msdn存档上看到了套接字客户端和服务器的一个很好的工作示例,它可以扩展到500个连接(正如我在其中一个项目改编中测试过的那样)但是目前我无法通过谷歌搜索找到该链接。 。但这里是msdn档案中关于同一主题的另一个链接,希望它会对你有所帮助 - Get Closer to the Wire with High-Performance Sockets in .NET ..
首先,我只能为您提供最终实施的想法,如果可能的话,还有一些简短的示例代码段。好的,我可以了解更多详情
我认为你可以跳到最后一段的链接。 ;)强>
让我强调一次,因为我想,我说SendAsync
和ReceiveAsync
不是BeginReceive/EndReceive
和BeginSend/EndSend
,即基于事件的异步模式(EAP)
使用Async形式的Socket方法的好处是它们是无异常的套接字编程方法,可以证明比BeginSend / EndSend方法更快。
以下是我发现最多500个PARALLEL连接的示例链接 - Networking Samples for .NET v4.0
因为您需要使用.NET 4.5的await / async功能。以下是.NET 4.5代码片段,其中显示了WebSocket
类的用法,其中也可以适用于Socket
实现 - Support for WebSockets Protocol(我猜WebSocket的AspNetWebSocketContext
将是Socket的{{ 1}})
我发现了来自Awaiting Socket Operations的MSDN - Parallel Programming team blog示例代码,可用于从.NET 4.5框架实现await / async。
我希望这证明对你有帮助。