программно перерабатывать пул из приложения asp.net в том же пуле

Иметь веб-приложение ASP.net, которое отлично работает в течение нескольких дней, но затем случайным образом выдает исключение из строки подключения к базе данных, и в результате в таблице отображаются 0 записей (их должно быть сотни). Я потратил много недель на отладку, память в порядке, база данных существует, и она исправлена ​​с помощью всего, что может привести к перезагрузке приложения. Требуется много дней ожидания, чтобы даже воспроизвести.

Поэтому я подумал, поскольку знаю, что никогда не должно быть 0 записей, как я могу заставить пул приложений, выполняющих веб-приложение, перезапускаться (когда я получаю это исключение из базы данных или 0 записей). По крайней мере, так веб-сайт будет работать для следующего пользователя, и мне не нужно его перезапускать вручную.

29.10.2009 18:38:30
2 ОТВЕТА
РЕШЕНИЕ

Привет в этой статье вы можете найти соответствующий код для перезапуска пула приложений с Asp.net

Перезапустите пул приложений IIS со страницы ASP.NET

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());
        }
    }
}
3
29.10.2009 18:41:45
это работает, если вызвано тем же пулом приложений, который я хочу перезапустить?
Tuviah 29.10.2009 18:51:39
@Tuviah: Не могли бы вы попробовать код, он должен делать то же самое с тем же пулом приложений, на котором вы работаете.
Tarik 29.10.2009 18:57:19
@Ps: если он не работает в одном и том же пуле приложений, вы можете создать страницу, работающую в другом пуле приложений, и запустить эту страницу, чтобы перерабатывать нужный пул приложений. Он становится как отдельный работник для обработки ваших работ.
Tarik 29.10.2009 19:01:41

Я никогда не чувствовал себя полностью комфортно с этим решением из-за сложности, а также из-за того, что требования безопасности неясны (и если для этого вам нужно предоставить права пользователю приложения, это не только еще один шаг настройки, но и безопасность). риск, и кажется, что предоставление пользователю приложения прав на беспорядочную переработку пула приложений, особенно по сети, может быть использовано при атаке DOS).

В моей ограниченной ситуации, когда я обнаружил критические условия, которые я смог разрешить с помощью перезапуска и обнаружить во время выполнения, но еще не смог предотвратить более приемлемые изменения кода, и после долгих исследований я прошел через несколько других решений (ОК - хаки ), чтобы сделать это. 1. Создайте необработанное исключение для вновь порожденной нити, 2. Environment.Exit()и 3 System.Web.HttpRuntime.UnloadAppDomain().. Они имеют довольно неприятный побочный эффект - завершение всех выполняющихся запросов, что, по общему признанию, является ужасным взломом, но допустимо в некоторых случаях (например, когда обнаруженное условие препятствует надлежащей обработке подавляющего большинства запросов в любом случае).

Отвращение к этому взлому оставалось со мной в течение многих лет, пока я недавно не наткнулся на этот маленький драгоценный камень, который намного проще и WMIполностью избегает :

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

Мое тестирование показало, что оно делает именно то , что мне было нужно, и я верю, что вы тоже этого хотели. Согласно документации, он существует с тех пор .NET 2.0, но я никогда не сталкивался с этим в своих исследованиях, пока пару дней назад.

4
13.01.2015 22:28:38
Спасибо за это. Мы давно используем HttpRuntime.UnloadAppDomain();, не могли бы вы объяснить, чем отличается ваше предложение?
Alex 17.07.2019 14:05:06
Я думаю, что HttpRuntime.UnloadAppDomain();прервет любые запросы в процессе. InitiateShutdownотклоняет новые запросы, но завершает любые, которые уже выполняются.
James 17.07.2019 16:43:37