2011-07-20 25 views
3

我的一位朋友在家中托管了一个ASP.NET 2.0应用程序,直到他移动并且我提出将它托管在我自己的Win7/IIS7/SQLE2008r2上服务器。在Windows窗体中不调用SqlConnection.Close() - 为什么它有时会起作用

当我把代码我的服务器上,短短几年后,请求我会得到这个错误:

Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.

首先,我打开了最大池大小,暂时“修复”的问题。然后我仔细看了一下他的代码。原来,他从来没有打电话给SqlConnection.Close()。所以我添加了关闭并从所有连接字符串中删除了最大池大小,并且问题解决了。

我问他如何解决这个问题,如果他在某种程度上增加了默认服务器的默认最大池大小web.config或其他东西。他回答说:“.NET垃圾收集”。所以他依靠垃圾收集来关闭他的数据库连接,并在他的服务器上工作。但在我看来,它并没有。

任何人都可以解释为什么吗?他正在度假,所以我不想打扰他向他询问版本等细节,但我猜他会运行Win2k8。

+0

我应该补充说,我知道这不是一个好习惯,而且我知道如何正确地做,以及为什么。我的主要问题是为什么它长时间在他的服务器上运行良好。这只是他内存太少导致GC更积极的问题吗? – carlsb3rg

回答

4

Jeff Atwood has a wonderful article about this very thing, I highly recommend this read.

依托.NET垃圾收集关闭SQL连接是一个没有没有。 SqlConnection.Close(),以及Dispose()应该始终被称为,但至少Close()Note that the using keyword will take care of disposing objects automatically for you (example).

依靠GC来做任何事情是不负责任和愚蠢的。这就像忽略了所有的内存,并说:“哦,当用户用完内存,他们可以重新启动!:D”。

在坚果壳中,不在新部署网站上工作的代码不是您的错。在这种情况下,它是不负责任的SQLConnection处理的编码器。

2

依靠垃圾收集器关闭连接的问题是你不能。

如果您将垃圾收集器的连接ojbects清理干净,则无法控制发生的时间。垃圾收集器最终会关闭它们,但是当发生这种情况取决于很多因素时,例如有多少可用内存以及使用了多少内存。这些因素会因服务器而异,但随着时间的推移也会发生变化,所以即使在同一台服务器上,您甚至不能指望垃圾收集器始终保持相同的工作状态。

不同的数据库反应不同,因为有很多未关闭的连接。例如Access数据库对此非常敏感,不允许超过64个连接。

无论如何,你应该总是关闭你的连接和你的数据读取器。此外,您应该使用using块或try...finally块来确保连接确实始终处于关闭状态,即使代码中出现问题。

0

只要垃圾收集的速率超过创建新连接的速度,将其留在垃圾收集器中就可以了。但是我从来没有见过任何人以这种方式使用ASP.NET。

你不应该调用SqlConnection.Dispose的唯一时间是当你绝对不能。例如,从拥有它的类的析构函数中调用它会随机抛出一个异常,所以如果这是你唯一的希望,那么就把连接打开。

+1

把它留给垃圾回收就太不好了。 :(请记住,总是像下一个阅读它的人一样是一个疯子,他拥有一把砍刀并知道你住在哪里! –

相关问题