web-dev-qa-db-fra.com

Comment empêcher une application ASP.NET de redémarrer lorsque le fichier web.config est modifié?

J'héberge le runtime ASP.NET via la méthode ApplicationHost.CreateApplicationHost. Lorsque je modifie le web.config alors que l'application est en cours d'exécution, je vois beaucoup de ThreadAbortExceptions de première chance levés. Ceci est juste avant que mon application tombe en panne. Je suppose que cela est dû au fait que le moteur d'exécution a détecté des modifications de la configuration et souhaite redémarrer.

Ce scénario n'est pas vraiment pris en charge pour nous, je préférerais donc simplement désactiver le rechargement automatique.

Est-ce que quelqu'un sait comment faire ça?

30
Jacob Stanley

Autant que je sache, il n’existe aucun moyen de désactiver ce comportement, les modifications apportées à Webconfig forcent le redémarrage de l’application.

Mise à jour: il est effectivement possible, il existe un certain nombre de méthodes bien documentées, comme expliqué dans cette réponse

Réponse originale:

Il y a une question similaire ici juste pour une autre référence. J'ai trouvé des informations supplémentaires qui pourraient être utiles.

Les modifications de configuration entraînent un redémarrage Du domaine d'application
Les modifications apportées aux paramètres de configuration Dans les fichiers Web.config Entraînent indirectement le redémarrage du domaine de l'application . Ce comportement Se produit par conception. Vous pouvez éventuellement Utiliser l'attribut configSource pour Référencer des fichiers de configuration externes Qui ne provoquent pas de redémarrage lorsqu'une modification de Est effectuée. Pour plus d'informations, Voir configSource dans Attributs généraux Hérité de la section Eléments.

De Cet article MSDN

Clause de non-responsabilité: j’ai écrit l’autre réponse et, normalement, je n’aurais pas fait référence à moi-même, mais j’ai trouvé le lien suffisant ici depuis 8 ans, c’est vraiment très différent: une solution est très simple en cliquant sur la IIS front-end et des solutions de contournement existent depuis ASP.NET 1.0.

26
Quintin Robinson

En fait, les deux premières réponses sont incorrectes. Il est est possible et assez facile d'empêcher ce recyclage. Cette fonctionnalité est disponible depuis au moins IIS6.

Méthode 1 (à l'échelle du système)

Remplacez le paramètre de registre DWORD pour HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNMode par la valeur 1, ce qui désactive les notifications de modification all file.

Ne soyez pas dérouté par l'emplacement: Wow6432Node n'a, dans ce cas, aucune influence sur le nombre de bits de votre application Web.

Méthode 2 (.NET 4.5+)

Si vous utilisez .NET 4.5, alors il est maintenant possible de désactiver ceci au niveau de chaque site , utilisez simplement les éléments suivants dans votre web.config:

<httpRuntime fcnMode="Disabled"/> 

Méthode 3 (IIS6 +)

Enfin, et au moins depuis IIS6, il existe un paramètre appelé DisallowRotationOnConfigChange comme paramètre uniquement pour le pool d’applications (du moins c’est ce que le texte sur MSDN tente de dire, mais testé Définissez-la sur true et les modifications apportées à la configuration du pool d'applications n'entraîneront pas de recyclage immédiat.

Ce dernier paramètre peut également être défini à partir des paramètres avancés du pool d'applications:

Disable Recycling for Configuration Change

Méthode 4 (ASP.NET 1.0 et 1.1)

Pour les (anciens) sites Web utilisant ASP.NET 1.0 ou 1.1, il existe un bogue confirmé qui peut provoquer des recycles rapides et répétés lors des modifications de fichiers. La solution de contournement à l'époque était similaire à ce que MartinHN a suggéré sous la question principale, à savoir quelque chose comme ce qui suit dans votre web.config:

<compilation 
   debug="false"
   defaultLanguage="vb"
   numRecompilesBeforeAppRestart="5000">

Cela ne désactive pas le recyclage, mais seulement après que 5000 / les recompilations ont eu lieu. L'utilité de ce nombre dépend de la taille de votre application. Microsoft ne dit pas clairement en quoi consiste un recompilation . La valeur par défaut est 15 .

En passant: quelle que soit la version de .NET ou Windows, nous constatons que lorsque l'application est exécutée à partir d'un partage et utilisée dans un environnement à charge équilibrée, le site est recyclé en permanence. La seule façon de le résoudre consistait à ajouter ce paramètre FNCMode au registre (mais il existe maintenant plus d'options plus fines).

22
Abel

J'ai rencontré un problème encore plus grave qui allait dans le même sens: les modifications apportées à any fichier ou sous-dossier dans le répertoire de base AppDomain provoquaient l'arrêt de l'environnement d'hébergement. C’est un gros problème pour notre application, car nous exécutons une interface utilisateur WPF dans le même AppDomain et nous ne pouvons pas le redémarrer sans distraire l’utilisateur.

Je voulais vraiment éviter d'avoir à exécuter un AppDomain séparé pour la partie Web de l'application, j'ai donc fait quelques recherches avec Reflector. J'ai trouvé que le coupable était la classe interne FileChangesMonitor.

J'ai donc écrit un horrible horrible réflexe pour résoudre le problème. Je pensais que je le posterais ici comme solution potentielle pour quiconque ayant le même problème. Il vous suffit d'appeler HttpInternals.StopFileMonitoring() pour désactiver l'arrêt des modifications de fichiers/dossiers.

internal static class HttpInternals
{
    private static readonly FieldInfo s_TheRuntime = typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.NonPublic | BindingFlags.Static);

    private static readonly FieldInfo s_FileChangesMonitor = typeof(HttpRuntime).GetField("_fcm", BindingFlags.NonPublic | BindingFlags.Instance);
    private static readonly MethodInfo s_FileChangesMonitorStop = s_FileChangesMonitor.FieldType.GetMethod("Stop", BindingFlags.NonPublic | BindingFlags.Instance);

    private static object HttpRuntime
    {
        get
        {
            return s_TheRuntime.GetValue(null);
        }
    }

    private static object FileChangesMonitor
    {
        get
        {
            return s_FileChangesMonitor.GetValue(HttpRuntime);
        }
    }

    public static void StopFileMonitoring()
    {
        s_FileChangesMonitorStop.Invoke(FileChangesMonitor, null);
    }
}
20
Jacob Stanley

Une solution serait d'ajouter l'élément suivant à la section web.config: 

<httpRuntime
    waitChangeNotification="315360000"
    maxWaitChangeNotification="315360000"
/>
9
jfburdet

Comme mentionné par jfburdet, la solution consiste à utiliser waitChangeNotification et maxWaitChangeNotification.

Cela étant dit, vous devez savoir qu'ils ne fonctionnent pas sur IIS 7 si ASP.NET est exécuté en mode mixte: http://forums.iis.net/t/1149344.aspx

0
Hanan Schwartzberg