为什么我的foreach循环在ASP.NET MVC视图中这么慢?

时间:2009-10-09 21:06:09

标签: c# asp.net-mvc

我在视图中使用foreach来循环我的强类型模型并显示一个表格。只有25行和7列,大约需要280毫秒。这似乎很慢。在Views中使用循环是否应该知道一些性能技巧?

编辑:我的控制器从Azure表中获取数据,并使用ViewModel模式将其提供给View。我不知道这是否重要,但我的观点是在VB中,我的模型是在C#中。所以,他们在不同的项目中。我会想出一个精简的例子来张贴,但我现在已经跑出了门,今晚要晚点才能到达。我希望在人们周末回家之前我会抓住StackOverflow的人群,所以我的原始帖子很快就没有示例代码了。

编辑:我向Fiddler确认没有发生延迟加载。在渲染视图期间没有Fiddler活动。

编辑:如果我使用Azure表格中的数据提供视图,则需要280毫秒。如果我使用看起来像Azure表中的真实数据的伪数据来提供相同的View,则需要60毫秒。在任何一种情况下,Controller都会填充ViewModel对象并将其传递给View。两个实例中都使用相同的ViewModel类。我不明白。

编辑:我想我弄明白了。如果我首先包含代码,这对其他人来说也许是显而易见的。这是我的ViewModel:

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

如果我将上面的ViewModel传递给我的View,foreach需要280毫秒。如果我首先使用children.ToList()填充上面的ViewModel,那么View只需要60毫秒。但是,经过进一步调查,我发现在任何一种情况下总页面加载时间都是相同的。我想如果在我的控制器或我的视图中迭代IEnumerable并不重要,因为整体效果是相同的。我仍然不确定迭代children是什么,因为我确信它不会在那时点击数据库,正如Fiddler所证实的那样。

3 个答案:

答案 0 :(得分:4)

您是否正在使用Linq-to-SQL或其他默认加载的ORM?

我建议记录所有数据库调用(datacontext.Log =某些继承自TextWriter的类)并检查在View中迭代它们时是否正在懒惰地加载关联。

编辑:以下信息似乎与此问题无关,但我会将其留在此处,因为它可能对某人有用:

假设你在这里使用Linq-to-SQL(如果不是这样的话我会编辑它):

当你的模型foo有一个关联Bar(所以foo.Bar)并且你没有在datacontext中指定任何LoadOptions时,bar会被懒惰地加载(所以:调用时加载,就像你的View中可能发生的那样) View本质上是进入数据库的。这种情况发生在每一行。

执行以下操作:

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

此外,为了防止这种情况,请尝试将DataContext包装在using语句中:

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

现在,当一些关联被懒惰加载时,您的视图将生成异常,因为DataContext现在将被释放并且不可用于数据库操作。

答案 1 :(得分:0)

获取.NET 4.0 beta和VS 2010 beta,并使用

  

Parallel.Foreach()

编辑:上面的答案应该是轻微的 sarcastic 。虽然这不是一个真正的解决方案,但一旦你在VS 2010中获得了TPL的好处,你就会明白我的意思。

实际上,你正在循环什么,你在循环中做了什么,它实际上取决于你的代码结构,你的数据结构等。需要更多的信息,以获得比上述更少的讽刺答案。 / p>

答案 2 :(得分:0)

它真的只在视野中发生吗?也许在迭代期间执行数据库加载会降低整个过程的速度。你有没有实现某种延迟加载?您应该在该过程中检查数据库活动。