Почему мои циклы foreach в ASP.NET MVC View такие медленные? - PullRequest
1 голос
/ 10 октября 2009

Я использую foreach в своем представлении, чтобы зациклить мою строго типизированную модель и отобразить таблицу. Всего 25 строк и 7 столбцов - около 280 мсек. Это кажется медленным. Есть ли какой-то трюк с производительностью, который я должен знать для использования циклов в представлениях?

РЕДАКТИРОВАТЬ: Мой контроллер берет данные из таблицы Azure и передает их в представление с использованием шаблона ViewModel. Я не знаю, имеет ли это значение, но мои представления в VB, а мои модели в C #. Итак, они в отдельных проектах. Я придумаю уменьшенный пример, чтобы опубликовать, но сейчас я выбегаю за дверь и вернусь к этому позже этим вечером. Я надеялся, что поймаю толпу StackOverflow до того, как люди уедут домой на выходные, поэтому мой оригинальный пост был написан быстро без примера кода.

РЕДАКТИРОВАТЬ: я подтвердил с Fiddler, что не происходит отложенной загрузки. Во время рендеринга представления нет действий Fiddler.

РЕДАКТИРОВАТЬ: если я передаю представление с данными из таблицы Azure, это занимает 280 мсек. Если я передаю в то же представление поддельные данные, которые выглядят так же, как реальные данные из таблицы Azure, это займет 60 мсек. В любом случае, контроллер просто заполняет объект ViewModel и передает его в представление. Один и тот же класс ViewModel используется в обоих случаях. Я не понимаю.

РЕДАКТИРОВАТЬ: Я думаю, я понял это. Возможно, это было бы очевидно для всех остальных, если бы я сначала включил код. Вот моя ViewModel:

public class EmployeeChildrenViewModel
{
    public Employee employee;
    public IEnumerable<Child> children;
}

Если я передам вышеупомянутую ViewModel моему View, foreach займет 280 мсек. Если я сначала заполнил вышеупомянутую ViewModel children.ToList(), тогда просмотр займет всего 60 мсек. Однако после дальнейшего изучения я вижу, что общее время загрузки страницы одинаково в любом случае. Я думаю, не имеет значения, будет ли IEnumerable повторяться в моем контроллере или в моем представлении, поскольку общий эффект одинаков. Я до сих пор не уверен, что делает итерация по children, так как я точно знаю, что в тот момент она не попала в базу данных, как подтвердил Fiddler.

Ответы [ 3 ]

4 голосов
/ 10 октября 2009

Вы используете Linq-to-SQL или какой-либо другой ORM, который по умолчанию загружается лениво?

Я предлагаю регистрировать все вызовы базы данных (datacontext.Log = некоторый класс, который наследуется от TextWriter) и проверять, загружаются ли ассоциации лениво, когда вы выполняете их в представлении.

РЕДАКТИРОВАТЬ: Похоже, приведенная ниже информация не относится к этому вопросу, но я оставлю ее здесь, поскольку она может быть кому-то полезна:

Предположим, что вы используете Linq-to-SQL здесь (я отредактирую это, если это не так):

Когда в вашей модели foo есть ассоциативная строка (так foo.Bar), и вы не указываете никаких LoadOptions в текстовом тексте, Bar загружается лениво (так: загружается при вызове, как, вероятно, происходит в вашем представлении), что Вид по существу идет в базу данных. И это происходит для каждого ряда.

Сделайте что-то вроде следующего:

DataLoadOptions options = new DataLoadOptions();
options.LoadWith<Foo>(f => f.Bar);
context.LoadOptions = options;

Далее, чтобы избежать этого, попробуйте обернуть ваш DataContext в оператор using:

using(DataContext context = new DataContext())
{
}

Ваше представление теперь будет генерировать исключение, когда какая-то ассоциация загружается лениво, потому что DataContext уже будет удален и недоступен для операций с базой данных.

0 голосов
/ 10 октября 2009

Действительно ли это происходит только в поле зрения? Возможно, во время итерации вы выполняете загрузку базы данных, что замедляет весь процесс. У вас реализована какая-то ленивая загрузка? Вы должны проверить активность базы данных во время этого процесса.

0 голосов
/ 10 октября 2009

получите .NET 4.0 beta и VS 2010 beta и используйте

Parallel.ForEach ()

Редактировать: вышеуказанный ответ должен был быть слегка саркастическим . Хотя это неверное решение, как только вы воспользуетесь преимуществами TPL в VS 2010, вы поймете, что я имею в виду.

На самом деле, что вы зацикливаете, и что именно вы делаете в своем цикле, это действительно зависит от вашей структуры кода, ваших структур данных и т. Д. Вам нужно больше информации для менее саркастического ответа, чем выше.

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