我编写了一个多线程Socket Server应用程序,它接受超过1000个并发连接。最近我们有应用程序崩溃;在分析了转储文件之后,知道应用程序因堆损坏而崩溃。我发现在以下链接中讨论了同样的问题。
.NET Does NOT Have Reliable Asynchronouos Socket Communication? http://support.microsoft.com/kb/947862
并且讨论也提出了3种解决方案。
网络应用程序应该对其发布的未完成异步IO的数量设置上限。
使用Microsoft CCR
使用TPL
由于时间因素,我认为坚持#1,但我没有清楚的图片如何实现这一点。有人能给出一个好的起点吗?
还有没有人使用Async与TPL解决这个问题?
答案 0 :(得分:1)
你的意思是比你所指的答案中的blog posting that I linked to更好的起点?
问题在于:
由于上述原因,您需要对任何时候未完成的异步写入量进行硬性限制。您可以通过在发出异步写入之前递增计数器并在完成处理程序中将其递减来跟踪它。
一旦达到这个限制,你所做的就由你决定。在原始文章中,我赞成将要写入的数据放入的队列。然后,当发生写入完成时,该队列可以用作数据源。队列为空后,您可以再次正常发送。当然这只会移动问题 - 你仍然有一个由远程对等体(排队数据)控制的内存资源,但你也没有使用其他操作系统资源(非页面缓冲池,I / O页锁定限制,等)。
您可以在达到限制时停止对等发送 - 现在,您通过异步API构建的API需要具有“此时无法发送,稍后再试”从之前的发送返回以前总是“工作”。
如果您这样做,我还会认真考虑通过在一个连续的块中分配大块缓冲区并在池中使用它们来避免固定内存问题。
答案 1 :(得分:0)
首先,这是一篇非常古老的知识库文章。您如何确定 特定问题? 然后,正如Hans Passant在SO问题中回答的那样,如果你编写了错误的异步代码,它会咬你。如果你不处理你的资源(并且内存缓冲区是资源),并发程序将面临内存错误
使用原始线程编写好的并发代码非常困难,而TPL确实使其更容易,但它无法修复您已有的错误。实际上,除非您确定当前的问题,否则您可能会将它们转移到使用TPL的版本。
在不知道导致应用程序崩溃的具体问题的情况下,我只能提出一些建议:
您还可以使用其他技术,具体取决于您正在构建的应用程序类型。例如,您可以使用TPL DataFlow以独立的步骤中断处理。
至于CCR,在Robotics Studio之外使用它没什么意义。 TPL包含编写并发应用程序所需的大部分相关功能。