我有几个运行相同asp.net mvc web应用程序的Web服务器,连接到一个mongodb服务器。其中一个Web服务器不断抛出SocketException异常,即使我重新启动IIS。其他服务器工作正常。这不是第一次出现异常。几周前,另一个Web服务器也遇到了同样的问题,而当时其他服务器是正常工作的。错误信息如下:
“由于系统缺乏足够的缓冲区空间或队列已满,无法对套接字执行操作。”
“由于系统缺乏足够的缓冲区空间或队列已满,无法对套接字执行操作。”
现在我只能重启服务器来临时解决这个问题。我通过修改 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\MaxUserPort
为65534 来确保Web服务器的动态端口范围正确设置。现在我怀疑这是否是C# mongodb驱动程序的一个bug。我查看了驱动程序的源代码,特别是 MongoCursorEnumerator.cs,连接被释放的地方。类MongoCursorEnumerator<TDocument>
实现了IDisposable
并在其Dispose
方法中正确释放了连接。但它没有析构函数(finalizer),这保证在GC中调用Dispose
。
现在我确保项目中所有与连接相关的代码都被正确包装在using
块中。在这种情况下,缺少析构函数/终结器会导致SocketException吗?如果不是,那么这个异常的可能原因是什么?
更多信息:ASP.NET MVC 3,Windows Server 2008 R2,Mongo DB 2.0,Mongo Db Driver for C# 1.5
更新
最新版本的MongoDB C#驱动程序已解决此问题。
MongoCursorEnumerator<T>
实现了IEnumerable
接口,这意味着编译器会在 finally 块中发出对其 dispose 方法的调用。假设它在 foreach 循环中使用,就不需要终结器。如果手动使用枚举器,则有可能不会调用 dispose。 - Christopher Currens