从同一个池中的asp.net应用程序以编程方式回收池

时间:2009-10-29 18:38:31

标签: asp.net iis

有一个ASP.net网络应用程序可以正常工作几天,但随后会随机抛出一些数据库连接字符串异常,因此表中列出了0条记录(应该显示数百条)。我花了很多周调试,内存很好,数据库存在,并通过做任何会导致应用程序回收的东西来修复它。它需要很多天才能重现。

所以我在想,因为我知道应该永远不会有0条记录,如何强制运行Web应用程序的应用程序池进行回收(当我收到此数据库异常或0条记录时)。至少这种方式,网站将为下一个用户工作,我不必手动重新启动它。

2 个答案:

答案 0 :(得分:3)

您好在本文中可以找到从Asp.net重启应用程序池的相关代码

Restart IIS application pool from ASP.NET page

using System;
using System.Web;
using System.Web.UI;
using System.Management;
using System.DirectoryServices;
using System.Web.UI.WebControls;

public partial class iis : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Write(System.Environment.MachineName);
        status();
    }

    protected void status()
    {
        string appPoolName = "dev.somesite.com";
        string appPoolPath = @"IIS://" + System.Environment.MachineName + "/W3SVC/AppPools/" + appPoolName;
        int intStatus = 0;
        try
        {
            DirectoryEntry w3svc = new DirectoryEntry(appPoolPath);
            intStatus = (int)w3svc.InvokeGet("AppPoolState");
            switch (intStatus)
            {
                case 2:
                    lblStatus.Text = "Running";
                    break;
                case 4:
                    lblStatus.Text = "Stopped";
                    break;
                default:
                    lblStatus.Text = "Unknown";
                    break;
            }
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
    }
    protected void stopAppPool(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        string appPoolName = btn.CommandArgument;
        string appPoolPath = @"IIS://" + System.Environment.MachineName + "/W3SVC/AppPools/" + appPoolName;
        try
        {
            DirectoryEntry w3svc = new DirectoryEntry(appPoolPath);
            w3svc.Invoke("Stop", null);
            status();
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
    }

    protected void startAppPool(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        string appPoolName = btn.CommandArgument;
        string appPoolPath = @"IIS://" + System.Environment.MachineName + "/W3SVC/AppPools/" + appPoolName;
        try
        {
            DirectoryEntry w3svc = new DirectoryEntry(appPoolPath);
            w3svc.Invoke("Start", null);
            status();
        }
        catch (Exception ex)
        {
            Response.Write(ex.ToString());
        }
    }
}

答案 1 :(得分:2)

由于复杂性,我从未对此解决方案感到满意,但也因为安全要求不明确(如果您必须为此向应用程序用户授予权限,那不仅仅是另一个配置步骤,但也存在安全风险,似乎让应用程序用户有权不加选择地回收应用程序池,特别是在网络上,可以在DOS攻击中利用它。)

在我有限的情况下,我发现了一些关键条件,我能够通过重新启动来解决并在执行期间进行检测但是还无法通过更加可口的代码更改来阻止,经过大量研究,我经历了其他几个解决方案(OK - hacks )可以完成这项工作。 1.在新生成的线程上抛出未处理的异常,Environment.Exit()和3. System.Web.HttpRuntime.UnloadAppDomain()。这些具有相当令人讨厌的副作用,即终止所有进行中的请求,这无疑是一个可怕的黑客攻击,但在某些情况下是可以容忍的(例如,发现的情况阻止了对绝大多数请求的正确处理)。

这个黑客的厌恶一直伴随着我多年,直到我最近偶然发现了这个很多更简单的小宝石并完全避免了WMI

System.Web.Hosting.HostingEnvironment.InitiateShutdown();

我的测试表明它确实完全我需要的东西,我相信它也是你想要的。根据文档,自.NET 2.0以来它一直存在,但直到几天前我才在研究中遇到它。