在.Net 4.5中,我列出了包含加载耗时的对象的列表。一个包含5000个对象的列表大约需要5秒才能加载,因此对于每个循环执行需要相当长的时间。
由于对象的初始化是我一直想知道是否存在某种类型的列表,或者想要制作这样的列表的方法,其中对象在需要时逐步加载。
类似于列表,它可以知道有多少个对象,但只能在检索对象时实例化它们。这存在吗?或者是否可以制作这样的列表?
我正在寻找关于如何完成这项工作的建议(如果可行的话),那么bot C#或VB.Net代码就可以了。因此我添加了两个标签。
修改
我应该补充一点,我尝试过使用延迟加载,但这似乎只是推迟了列表的加载,这不是一个真正的解决方案。
修改
这是我现在正在使用的内容。请注意,我删除了我的懒惰尝试使用延迟加载并恢复到我以前的方式昨天(这实际上是没有Lazy
对象的延迟加载)
Public Class SISOverlayItemList : Inherits SISBaseObject : Implements IEnumerable(Of SISOverlayItem)
Default Public ReadOnly Property Item(ByVal Index As Integer) As SISOverlayItem
Get
Return New SISOverlayItem(Me.List(Index).ID, Me.Parent)
End Get
End Property
Public ReadOnly Property Items As List(Of SISOverlayItem)
Get
Dim output As New List(Of SISOverlayItem)
Call Me.List.Items.AsParallel.ForAll(Sub(i) output.Add(New SISOverlayItem(i.ID, Me.Parent))
Return output
End Get
End Property
Public ReadOnly Property Parent As SISOverlay
Get
Return Me._Parent
End Get
End Property
Private ReadOnly Property List As SISList
Get
If Me._List Is Nothing Then
Me._List = Me.Application.Lists(Me.Name)
End If
Call Me.Refresh()
Return Me._List
End Get
End Property
Private _List As SISList
Private _Parent As SISOverlay
Public Sub New(ByVal Parent As SISOverlay)
Me._Parent = Parent
Me._Application = Parent.Application
Me._Name = String.Format("Overlay_{0}_Items", Parent.Name)
Call Me.Refresh()
End Sub
Public Sub Refresh()
Call Me.Application.Lists(Me.Name).ScanOverlay(Me.Parent)
End Sub
Public Function GetEnumerator() As IEnumerator(Of SISOverlayItem) Implements IEnumerable(Of SISOverlayItem).GetEnumerator
Return Me.Items.GetEnumerator()
End Function
Private Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator
Return Me.GetEnumerator
End Function
结束班
将Items
中的所有对象转换为当前列表(List
的项目)的SISOverlayItem
属性需要很长时间。如果实例化ID
所需的SISOverlayItem
参数需要对存储在Application
的每个项目中的List
对象进行API调用,那么在转换过程中会花费多少时间}。
如果可以小批量执行这些调用,它应该删除实例化列表中每个对象所需的长延迟。
答案 0 :(得分:2)
听起来这些物品并不都存在,而这也是需要花费很长时间的一部分。如果您不需要将项目集合作为列表,那么值得研究yield return
。这样可以查询,过滤或枚举IEnumerable
。
它可能看起来像这样:
public readonly IEnumerable<SISOverlayItem> Items
{
get
{
SISOverlayItem myItem = intermediateList.DoSomeWork();
yield return myItem;
}
}
这可能不切实际。此外,如果涉及大量处理,这可能更适合作为方法而不是属性。如果您知道如何过滤集合,则可以执行以下操作:
public IEnumerable<SISOverlayItem> ProduceSelectedItems()
{
var intermediateItems = from item in intermediateList
where item.isSelected
select item;
foreach (var item in intermediateItems)
{
yield return item.DoSomeWork();
}
}
抱歉,我手边没有Visual Studio可以检查,但我认为这样的事情可能有所帮助。另一个概述这种方法的问题是here。