【问题标题】:programatically recycle pool from asp.net application in same pool以编程方式从同一池中的 asp.net 应用程序回收池
【发布时间】:2015-01-14 06:28:38
【问题描述】:

有一个 ASP.net Web 应用程序可以正常运行几天,但随后随机抛出一些数据库连接字符串异常,结果表中列出了 0 条记录(应该显示数百条)。我花了好几个星期调试,内存很好,数据库存在,并且通过做任何会导致应用程序回收的事情来修复它。甚至需要等待很多天才能复制。

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

【问题讨论】:

    标签: asp.net iis


    【解决方案1】:

    由于复杂性,我从来没有完全适应过这种解决方案,而且还因为安全要求不明确(如果您必须为此授予应用程序用户权限,那不仅是另一个配置步骤,而且还有一个安全风险,似乎让应用程序用户有权不加选择地回收应用程序池,尤其是在网络上,可能会被用于 DOS 攻击)。

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

    多年来,我一直对这种 hack 感到厌恶,直到我最近偶然发现了这个非常更简单并且完全避免 WMI 的小宝石:

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

    我的测试表明它正是我需要的,我相信这也是你想要的。根据文档,它从.NET 2.0 就已经存在,但直到几天前我才在研究中发现它。

    【讨论】:

    • 谢谢。我们已经使用HttpRuntime.UnloadAppDomain(); 很长时间了,您能解释一下您的建议有何不同吗?
    • 我认为HttpRuntime.UnloadAppDomain(); 将中止任何正在进行的请求。 InitiateShutdown 拒绝新请求,但会完成任何正在进行的请求。
    【解决方案2】:

    您好,您可以在本文中找到从 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());
            }
        }
    }
    

    【讨论】:

    • 如果由我希望回收的同一个应用程序池调用,这是否有效?
    • @Tuviah :您能否尝试一下代码,它应该对您正在运行的同一个应用程序池执行相同的操作。
    • @P.s : 如果不在同一个应用池中,可以创建一个在不同应用池下运行的页面,然后运行该页面来回收你想要的应用池。它变成了一个单独的worker处理您的工作。
    猜你喜欢
    • 2011-07-02
    • 2011-01-12
    • 2020-03-04
    • 2011-08-22
    • 1970-01-01
    • 2020-05-23
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多