Таинственный ASP.NET MVC Action Проблема с высокой задержкой? - PullRequest
11 голосов
/ 30 мая 2011

Используя инструменты разработчика Firebug и Chrome, я вижу, что загрузка некоторых файлов javascript и css с помощью действия может занять дополнительные 500 мс на моей машине для разработки. Это происходит с разными файлами при разных вызовах, и не имеет значения, в каком порядке я их помещаю. Если я ссылаюсь напрямую на файлы, эта задержка в 500 мсек никогда не возникает. Я могу обновлять страницу снова и снова и получать разные значения, но они всегда выглядят так, будто 500 мс были добавлены к времени запроса. Если я продолжаю обновлять страницу, дополнительные 500 мс отображаются в разных отдельных файлах или иногда в двух файлах, один из которых имеет задержку 1000 мс, как показано на рисунке ниже.


EDIT

Помещение Monitor.Enter в BeginRequest и Monitor.Exit моего HttpModule в EndRequest привело к тому, что задержка исчезла, поэтому я предполагаю, что это как-то связано с многопоточностью нескольких запросов.


Я использую метод, описанный Эваном Нагелем здесь для кэширования, но то же самое происходит, когда я заменяю ссылки вызовами на свой собственный контроллер действием, которое просто передает необработанный файл через:

public FileResult RawFile(string path, string contentType)
{
    var server = HttpContext.Server;
    string decodedPath = server.UrlDecode(path);
    string mappedPath = server.MapPath(decodedPath);
    return File(mappedPath, contentType);
}

Вот код, который у меня есть в разделе заголовка моего HTML:

<link rel="stylesheet" href="@Url.Action("RawFile", new { controller = "Content", path = "~/Content/Site.css", contentType = "text/css" })" type="text/css" />
<script src="@Url.Action("RawFile", new { controller = "Content", path = "~/Scripts/debug/FBINFO.js", contentType = "application/x-javascript" })" type="text/javascript"></script>
<script src="@Url.Action("RawFile", new { controller = "Content", path = "~/Scripts/jquery-1.4.1.min.js", contentType = "application/x-javascript" })" type="text/javascript"></script>

Похоже, что это не происходит на моем рабочем сервере, по крайней мере, не так часто, но труднее сказать, потому что задержка обычно выше. Не о чем ли беспокоиться? Что вызвало бы это? Это происходит как с Cassini, так и с моим локальным сервером IIS в 64-битной Windows 7 Home Ultimate.

Я добавил пользовательский атрибут для определения времени вызовов и времени между выполнением OnAction / OnResult и выполнением, как правило, меньше миллисекунды. Я использовал секундомер вокруг метода действия (ZipController пишет в поток ответов и не возвращает результат), и время также всегда мало, в среднем 1,5 мс и всегда меньше 10 мс.

Единственное реальное отличие, которое я вижу в заголовках Fiddler, - это заголовок X-AspNetMvc-Version, поэтому я установил, что он не добавляется, и даже удалил заголовок X-AspNet-Version безрезультатно. Я пытался включить и отключить сжатие и обо всем остальном, что я могу придумать. Это после того, как я добавил свои собственные заголовки Cache-Control и ETag, которые не имели никакого эффекта. Интересно, что задержка в 500 мс происходит даже в случае ответа 304 Not Modified, когда тело не отправляется. Иногда два файла будут иметь задержки, один 500 мс, а другой 1000 мс.

Прямой файл:

HTTP/1.1 200 OK
Content-Type: application/x-javascript
Last-Modified: Sun, 29 May 2011 22:42:27 GMT
Accept-Ranges: bytes
ETag: "b57a84af511ecc1:0"
Server: Microsoft-IIS/7.5
Date: Mon, 30 May 2011 04:38:20 GMT
Content-Length: 1336

Действие RawFile:

HTTP/1.1 200 OK
Cache-Control: public
Content-Type: application/x-javascript
ETag: "CD9F383D0537373C6D2DC8F60D6519A6"
Server: Microsoft-IIS/7.5
Date: Mon, 30 May 2011 04:34:37 GMT
Content-Length: 1336

Action Method Direct File

Следуя комментарию IanT8, я добавил модуль HttpModule для отслеживания запроса начала / окончания, а также добавил вызовы журнала в качестве первого и последнего операторов моих методов действия. Короче говоря, оба запроса поступают одновременно, и задержка в 500 мс происходит после первого EndRequest, до того, как будет выполнен метод действия второго вызова. Эта задержка обычно составляет 499 мсек, но однажды она составила 497 мсек, 498 мсек раз и 492 мсек раз.

2011-05-31 00:55:19.1874|INFO|20110531 00:55:19.196 BeginRequest: http://localhost:51042/Zip/Style?Path=~/Content/Site.css
2011-05-31 00:55:19.1874|INFO|20110531 00:55:19.197 BeginRequest: http://localhost:51042/Zip/Script?Path=~/Scripts/jquery-1.4.1.min.js|~/Scripts/debug/FBINFO.js
2011-05-31 00:55:19.2034|INFO|20110531 00:55:19.203 Style() Start
2011-05-31 00:55:19.2034|INFO|20110531 00:55:19.208 Style() End
2011-05-31 00:55:19.2034|INFO|20110531 00:55:19.212 EndRequest: http://localhost:51042/Zip/Style?Path=~/Content/Site.css
2011-05-31 00:55:19.7044|INFO|20110531 00:55:19.704 Script() Start
2011-05-31 00:55:19.7044|INFO|20110531 00:55:19.712 Script() End
2011-05-31 00:55:19.7044|INFO|20110531 00:55:19.713 EndRequest: http://localhost:51042/Zip/Script?Path=~/Scripts/jquery-1.4.1.min.js|~/Scripts/debug/FBINFO.js

Теперь о действительно интересной части. Я создал статический объект в моем модуле HttpModule и вызвал Monitor.Enter в BeginRequest и Monitor.Exit в EndRequest. Задержка исчезла. Chrome показывает, что один вызов занимает около 15-20 мс, а другой - около 30-40 мс, потому что он должен ждать окончания первого звонка, но задержка в 500 мс прошла. Очевидно, что это решение не является оптимальным.

Ответы [ 2 ]

6 голосов
/ 30 мая 2011

Попробуйте отключить сеанс (SessionStateAttribute).

0 голосов
/ 10 июня 2011

Существует известная проблема с Cassini и связанные с производительностью проблемы с отображением файла хоста IPv6 через IPv4, а также с разрешением номера порта, которое Cassini использует в Windows 7. Он уже ответил в переполнении стека и решает проблемывидел в Firefox и Chrome.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...