什么是设计应用程序的常用方法,它强烈依赖于C#
(LINQ
,IEnumerable
,IQueryable
,...)中的惰性评估?C#懒惰问题
现在我通常试图使每个查询懒越好,使用yield return
和LINQ
的查询,但在运行时,这可能通常会导致“懒得”行为,当每一个查询获取从中竣工图就要开始明显导致在严重的视觉表现下降。
我通常的做法是将ToList()
投影算子放在某处缓存数据,但我怀疑这种方法可能不正确。
什么是从一开始就设计这类应用程序的适当/常用方法?
什么是设计应用程序的常用方法,它强烈依赖于C#
(LINQ
,IEnumerable
,IQueryable
,...)中的惰性评估?C#懒惰问题
现在我通常试图使每个查询懒越好,使用yield return
和LINQ
的查询,但在运行时,这可能通常会导致“懒得”行为,当每一个查询获取从中竣工图就要开始明显导致在严重的视觉表现下降。
我通常的做法是将ToList()
投影算子放在某处缓存数据,但我怀疑这种方法可能不正确。
什么是从一开始就设计这类应用程序的适当/常用方法?
我发现将每个IEnumerable分类到三个类别之一很有用。
对于1类,我倾向于保持混凝土类型在适当的时候,阵列或IList的等 对于3类,这些都是最好的本地内保持一种方法,以避免难以发现的错误。 然后我们有第2类,并且一如既往在优化性能时,首先要测量以找出瓶颈。
一些随机的想法 - 因为这个问题本身是松散的定义:
我需要的数据有一定的顺序进行缓存,调用聚合运营商之一(ToList
,ToArray
,等等)。否则,只需使用懒惰评估。
围绕您的数据构建代码。什么数据是不稳定的,每次都需要重新刷新?使用懒惰评估,不要缓存。哪些数据相对静态,只需要拉一次?将这些数据缓存在内存中,以免不必要地使用它。
非常广泛的问题,不幸的是你会听到很多:这取决于。延迟加载很好,直到没有。
一般来说,如果您反复使用相同的IEnumerables,最好将它们缓存为列表。
但是,对于您的呼叫者来说,这种情况很少有人知道这一点。也就是说,如果您从存储库或某个东西获取IEnumerables,最好让存储库完成其工作。它可能会将其缓存为内部列表,也可能每次都将其构建起来。如果来电者试图让太聪明了,他们可能会错过数据改变等
我会建议返回DTO
public IList<UserDTO> GetUsers()
{
using (var db = new DbContext())
{
return (from u in db.tblUsers
select new UserDTO()
{
Name = u.Name
}).ToList();
}
}
在你上面的例子做之前你DAL一个ToList 有在DbContext作用域结束之前执行ToList()。
推迟执行并使用.ToList()
缓存所有项目不是唯一选项。第三个选项是缓存的项目,而通过使用惰性列表进行迭代。
执行仍然是延期,但所有项目只产生一次。这是如何工作的一个例子:
public class LazyListTest
{
private int _count = 0;
public void Test()
{
var numbers = Enumerable.Range(1, 40);
var numbersQuery = numbers.Select(GetElement).ToLazyList(); // Cache lazy
var total = numbersQuery.Take(3)
.Concat(numbersQuery.Take(10))
.Concat(numbersQuery.Take(3))
.Sum();
Console.WriteLine(_count);
}
private int GetElement(int value)
{
_count++;
// Some slow stuff here...
return value * 100;
}
}
如果您运行测试()方法时,_count
只有10.没有缓存这将是16,并用。 ToList()
这将是40!
神圣莫里!我有一吨代码,看起来几乎与此相同! :) – 2011-04-12 12:41:48