C# 如何阻止异步tcp.NET代码耗尽整个系统';s资源

C# 如何阻止异步tcp.NET代码耗尽整个系统';s资源,c#,.net,asynchronous,tcp,C#,.net,Asynchronous,Tcp,在我的一些异步tcp服务器代码中,偶尔会发生一个错误,导致进程占用整个系统的内存。在查看日志、事件查看器和一些日志时,如果“调用应用程序多次对同一客户机进行异步IO调用,那么如果远程客户机停止其I/O结束,您可能会看到堆碎片和专用字节增加”这会导致System.Threading.OverlappedData结构和字节数组的内存使用和固定出现峰值 KB文章提出的解决方案是“为异步IO的未完成缓冲区数量(发送或接收)设置上限。” 如何做到这一点?这是指发送到BeginRead的字节[]?那么,解决

在我的一些异步tcp服务器代码中,偶尔会发生一个错误,导致进程占用整个系统的内存。在查看日志、事件查看器和一些日志时,如果“调用应用程序多次对同一客户机进行异步IO调用,那么如果远程客户机停止其I/O结束,您可能会看到堆碎片和专用字节增加”这会导致System.Threading.OverlappedData结构和字节数组的内存使用和固定出现峰值

KB文章提出的解决方案是“为异步IO的未完成缓冲区数量(发送或接收)设置上限。”

如何做到这一点?这是指发送到BeginRead的字节[]?那么,解决方案是否只是用信号量包装访问字节[]

编辑:信号量控制的字节缓冲区访问或仅仅拥有静态大小的字节缓冲区池是两种常见的解决方案。我仍然担心的是,当这个异步客户机问题发生时(实际上可能是某种奇怪的网络事件),有信号量或字节缓冲池将防止我耗尽内存,但这并不能解决问题。我的缓冲池可能会被问题客户机占用,实际上是将正确的功能合法客户机锁定在外


编辑2:遇到了这个伟大的。基本上,它显示了如何手动取消绑定对象。虽然异步TCP代码保留了后台运行时规则的固定,但可以通过在使用前显式固定每个缓冲区,然后在块末尾或最后一个缓冲区中取消固定来覆盖该规则。我现在正试图弄明白…

解决这个问题的一种方法是预先分配缓冲区和异步通信中使用的其他数据结构。如果在启动时预先分配,则不会出现碎片,因为内存自然会驻留在堆的同一区域中

我建议使用添加到.Net 3.5 SP1中的
ReceiveAsync
/
sendaync
API,它允许您缓存或预分配
SocketAsyncEventArgs
结构和存储在
SocketAsyncEventArgs.buffer
属性中的内存缓冲区,与较早的
BeginXXX
/
EndXXX
api不同,后者只允许缓存或预分配内存缓冲区

使用旧的API也会带来巨大的CPU成本,因为API在内部创建的Windows一次又一次地重叠I/O结构。在新的API中,这发生在
SocketAsyncEventArgs
中,因此通过将这些对象合并,CPU成本只需支付一次


关于您关于固定的更新:固定是有原因的,即防止GC在碎片整理期间移动缓冲区。手动取消钉扎可能会导致内存损坏。

可能重复:这是关于用信号量包装调用以开始。也许这是分析代码的一个很好的理由…@giacomo我希望我有一个分析器。停止希望,只需下载一个eval或免费分析器。