Как предотвратить перезапуск приложения ASP.NET при изменении web.config?
Я размещаю среду выполнения ASP.NET через ApplicationHost.CreateApplicationHost
метод. Когда я изменяю web.config
пока приложение работает, я вижу много первого шанса ThreadAbortException
брошен. Это как раз перед тем, как мое приложение падает. Я предполагаю, что это потому, что среда выполнения обнаружила изменения в конфигурации и хочет перезапустить.
Для нас этот сценарий не поддерживается, поэтому я бы предпочел отключить автоматическую перезагрузку.
Кто-нибудь знает как это сделать?
5 ответов
Насколько мне известно, нет способа отключить это поведение, изменения в webconfig заставляют приложение перезапускаться.
Обновление: это действительно возможно, есть ряд методов, хорошо документированных, как объяснено в этом ответе *
Оригинальный ответ:
Здесь есть похожий вопрос только для справки. Я нашел дополнительную информацию, которая может быть полезной.
Изменения конфигурации вызывают перезапуск домена приложения
Изменения параметров конфигурации в файлах Web.config косвенно приводят к перезапуску домена приложения. Такое поведение происходит по замыслу. При желании вы можете использовать атрибут configSource для ссылки на внешние файлы конфигурации, которые не вызывают перезапуск при внесении изменений. Для получения дополнительной информации см. ConfigSource в Общих Атрибутах, Унаследованных Элементами Раздела.
* Отказ от ответственности: я написал другой ответ и, как правило, не делаю ссылки на себя, но нахожу это достаточно релевантным, чтобы ссылаться здесь, так как через 8 лет после этого поста это действительно совсем другое: решение очень легко, нажав через IIS -end, и обходные пути существуют начиная с ASP.NET 1.0.
На самом деле, первые два ответа неверны. Можно и довольно легко предотвратить эту переработку, и эта функция была доступна по крайней мере с IIS6.
Метод 1 (общесистемный)
Изменить DWORD
настройки реестра для HKLM\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\FCNMode
к стоимости 1
, который отключит все уведомления об изменении файла.
Не смущайтесь местоположением: Wow6432Node
в этом случае не влияет на разрядность вашего веб-приложения.
Метод 2 (.NET 4.5+)
Если вы используете.NET 4.5, то теперь можно отключить это на уровне сайта, просто используйте следующее в вашем web.config
:
<httpRuntime fcnMode="Disabled"/>
Метод 3 (IIS6+)
Наконец, а также (по крайней мере), начиная с IIS6, есть настройка под названием DisallowRotationOnConfigChange
в качестве настройки только для пула приложений (по крайней мере, это то, что я думаю, что текст в MSDN пытается сказать, но я не проверял это). Установите это true
и изменения в конфигурации пула приложений не приведут к немедленной перезагрузке.
Этот последний параметр также можно настроить в разделе "Дополнительные параметры" пула приложений:
Метод 4 (ASP.NET 1.0 и 1.1)
Для (старых) веб-сайтов, использующих ASP.NET 1.0 или 1.1, существует подтвержденная ошибка, которая может вызывать быстрые и повторные повторы при изменении файла. Обходной путь в то время был похож на то, что MartinHN предложил по основному вопросу, а именно что-то вроде следующего в вашем web.config
:
<compilation
debug="false"
defaultLanguage="vb"
numRecompilesBeforeAppRestart="5000">
Это не отключает утилизацию, но делает это только после 5000 перекомпиляций. Полезность этого числа зависит от размера вашего приложения. Microsoft не совсем ясно говорит, что такое на самом деле перекомпиляция. По умолчанию, однако, 15.
Кроме того, независимо от версии.NET или Windows, мы обнаруживаем, что когда приложение запускается из общего ресурса и используется в среде с балансировкой нагрузки, сайт постоянно перезагружается. Единственный способ решить эту проблему - добавить FNCMode
установка в реестр (но теперь есть более детальные варианты).
Я столкнулся с еще большей проблемой в том же духе - изменения в любом файле или подпапке в базовом каталоге AppDomain приводят к закрытию среды размещения. Это довольно большая проблема для нашего приложения, так как мы запускаем пользовательский интерфейс WPF в том же домене приложений, и мы не можем перезапустить его, не мешая работе пользователя.
Я действительно хотел избежать запуска отдельного AppDomain для веб-части приложения, поэтому я покопался в Reflector. Я обнаружил, что виновником был внутренний класс FileChangesMonitor
,
Поэтому я написал ужасную ужасную рефлексию, чтобы решить проблему. Я думал, что опубликую это здесь как потенциальное решение для любого другого, имеющего ту же самую проблему. Вам просто нужно позвонить HttpInternals.StopFileMonitoring()
отключить выключение при изменении файла / папки.
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);
}
}
Решением было бы добавить следующий элемент в раздел web.config:
<httpRuntime
waitChangeNotification="315360000"
maxWaitChangeNotification="315360000"
/>
Как упомянуто jfburdet, решение состоит в том, чтобы использовать waitChangeNotification и maxWaitChangeNotification.
При этом вы должны знать, что они не работают на IIS 7, если ASP.NET запущен в смешанном режиме: http://forums.iis.net/t/1149344.aspx