Здесь много изложения, но это необходимо.
Не знаете, сколько людей знают об этом, но редактор кода Razor в Visual Studio заставляет ваш сайт "тестироваться" до самого события Application_Start
, и это вызывает некоторые неприятные проблемы в мой текущий проект, который использует WebActivator для многого инициализации сайта.
Обновление - при ближайшем рассмотрении это не просто Razor - похоже, что это Visual Studio-wide - отсюда изменение названия
Мне нужно иметь возможность обнаруживать, когда код сайта выполняется Visual Studio, а не веб-сервером.
Чтобы продемонстрировать - сделайте следующее ( точно как написано для обеспечения его воспроизведения):
- Создайте новый сайт MVC 4, я использовал шаблон интернет-приложения, поэтому на его создании было несколько страниц.
- Добавить пакет WebActivator из nuget
- Добавьте класс в папку App_Start с именем
RazorPageBugTest
- Вставьте этот код (изменив соответствующее пространство имен):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcApplication6.App_Start;
using System.IO;
[assembly: WebActivator.PreApplicationStartMethod(
typeof(RazorPageBugTest), "Start", Order = 0)]
namespace MvcApplication6.App_Start
{
public static class RazorPageBugTest
{
public static void Start()
{
using (var writer = File.Open(@"c:\trace.txt", FileMode.Create))
{
using (var tw = new StreamWriter(writer))
{
tw.AutoFlush = true;
tw.WriteLine("Written at {0}", DateTime.Now);
}
}
}
}
}
Обратите внимание, что этот код не является тем, что обычно работает на веб-сервере, так как он записывает на диск C: (действительно, это может не работать на вашем компьютере, если вы не запускаете VS как администратор).
- Теперь создадим проект.
- Этот следующий бит работает лучше всего, если у вас уже открыт Explorer на C: как только это будет завершено, найдите представление Razor и откройте его.
- Подождите, пока все биты С#/VB будут выделены.
- Посмотрите на диск C - oh look, там файл под названием "trace.txt" и дата в течение последних нескольких секунд!
Итак, это демонстрирует проблему здесь - редактор кода Razor запускает AppDomain и, фактически, обходит сайт, чтобы получить intellisense (включая такие вещи, как вещи в папке App_Helpers и т.д.). Теперь он фактически не вызывает метод Application_Start
, но когда у вас есть WebActivator и в проекте, любой из его методов запуска до запускается.
В моем случае это вызывает огромные проблемы: высокая загрузка процессора и использование памяти в devenv.exe
(что эквивалентно только что запущенному веб-сайту), потому что я инициализирую контейнеры DI и бог знает, что еще на данный момент, но один в особенно на самом деле раздражает.
На моем веб-сайте есть компонент, который прослушивает в сети сообщения о статусе и кэшировании с других компьютеров в веб-ферме. В средах QA и Live этот слушатель никогда не перестает открывать порт и слушать - на моей машине dev, однако он часто терпит неудачу - говорит, что порт уже используется. Когда я ищу процесс, который его открывает, он всегда devenv.exe
.
Вы уже догадались - я начинаю этот прослушиватель в инициализированном вызове загрузки WebActivator.
Итак, вопрос: кто-нибудь знает, как обнаружить, что код не запускается "правильным" веб-хостом, поэтому я могу остановить его запуск? Я особенно надеюсь на это, так как это также означает, что мои опыты по редактированию Visual Studio и Razor в итоге станут черным сайтом быстрее!
В качестве бонуса любое исправление может быть законно отправлено Дэвиду Эббо - автору WebActivator - поэтому он может использовать его ранее в своем стеке, чтобы полностью предотвратить проблему!
Обновление
Я только что добавил проблему на страницу WebActivator в GitHub, чтобы узнать, может ли Дэвид Эббо нажать на мое исправление или на лучшее, вниз в компонент WebActivator.