我有一个使用Nhibernate和Linq2SQL的复杂服务器应用程序。每天大约3次Linq2sql代码生成一个"值不能为空"例外。一旦发生这种情况,代码将始终生成异常。诊断和解决根本原因将是漫长的并且将引入不稳定性。
当前"修复"是每小时重新调用应用程序池。但是,从问题发生到恢复发生之前,服务已经停止。我希望Web服务能够捕获异常并回收它自己的应用程序池。我希望所有其他Web请求在完成之前得到尊重。
编辑:错误发生在负载均衡的Web场上的两台服务器上。客户端不会因为此代码崩溃而从一台服务器切换到另一台服务器。
答案 0 :(得分:23)
以下代码将回收当前站点的应用程序池。您需要添加对Microsoft.Web.Administration
的引用using (ServerManager iisManager = new ServerManager())
{
SiteCollection sites = iisManager.Sites;
foreach (Site site in sites)
{
if (site.Name == HostingEnvironment.ApplicationHost.GetSiteName())
{
iisManager.ApplicationPools[site.Applications["/"].ApplicationPoolName].Recycle();
break;
}
}
}
答案 1 :(得分:2)
将ASP.NET工作进程“跳转”到回收应用程序池的最简单方法是以某种方式修改web.config文件。此更改由文件系统观察程序获取,并导致ASP.NET回收以加载新配置。
文件的内容不必以任何实际方式改变;只需添加或删除空白字符即可。
修改强>
如果这还不足以解决您的问题,您可以全力以赴并使用目录服务手动回收应用程序池。
// Set up the path identifying your application pool.
var path = "IIS://YOURSERVERNAME/W3SVC/AppPools/YourAppPoolName";
// Create the directory entry to control the app pool
var appPool = new DirectoryEntry(path);
// Invoke the recycle action.
appPool.Invoke("Recycle", null);
基于Code Project: Recycling IIS 6.0 application pools programmatically。
答案 2 :(得分:0)
我以前遇到过完全相同的问题;我应该写博客,因为现在我不记得根本原因。
我的直觉告诉我,这是以下之一:
或者那些东西。只要确保你正确使用Linq2Sql。
答案 3 :(得分:0)
我最终选择的解决方案是为appPool允许使用的内存量设置最大值。然后代码只是吞噬了内存,直到asp.net决定回收appPool。
在App pool高级设置中,我将Private Memory Limit设置为800,000 Kb。
在Linq代码失败的Catch部分,我分配的内存超过了限制:
List<string> listOfMemory = new List<string>();
// in the app pool, you need to set the virtual memory limit to 800,000kb
log.Error("Allocating so much memory that the app pool will be forced to recycle... ");
for (int intCount = 1; intCount < 10000000; intCount++)
{
listOfMemory.Add("new string " + intCount.ToString());
}
现在这意味着在生成新的w3wp进程之前,只有大约4个线程失败。在此解决方案之前,线程将始终失败,直到人员手动回收应用程序池。不幸的是,如果您将应用程序池设置为在常规分钟数内循环,则分钟数越小,崩溃的频率就越高。分钟数越大,线程就会失败。
此创意解决方法可以限制损坏。