如何以编程方式回收.net Web应用程序自己的apppool?

时间:2012-02-27 18:23:10

标签: asp.net iis-7

我有一个使用Nhibernate和Linq2SQL的复杂服务器应用程序。每天大约3次Linq2sql代码生成一个"值不能为空"例外。一旦发生这种情况,代码将始终生成异常。诊断和解决根本原因将是漫长的并且将引入不稳定性。

当前"修复"是每小时重新调用应用程序池。但是,从问题发生到恢复发生之前,服务已经停止。我希望Web服务能够捕获异常并回收它自己的应用程序池。我希望所有其他Web请求在完成之前得到尊重。

编辑:错误发生在负载均衡的Web场上的两台服务器上。客户端不会因为此代码崩溃而从一台服务器切换到另一台服务器。

4 个答案:

答案 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)

我以前遇到过完全相同的问题;我应该写博客,因为现在我不记得根本原因。

我的直觉告诉我,这是以下之一:

  1. 某个环境没有被处理掉。
  2. 线程问题:确保多个线程无法访问相同的上下文。
  3. 或者那些东西。只要确保你正确使用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个线程失败。在此解决方案之前,线程将始终失败,直到人员手动回收应用程序池。不幸的是,如果您将应用程序池设置为在常规分钟数内循环,则分钟数越小,崩溃的频率就越高。分钟数越大,线程就会失败。

此创意解决方法可以限制损坏。