头脑风暴:如何在Silverlight中实现背景计算?
我目前正在开发一个Silverlight 4.0应用程序,它在da DataGrid控件中显示大约13.000行。单个项包含大约40个字符串属性和一个整数属性 在包含该网格的页面上有一个面板,用户可以在其中设置不同的权重。单击“更新”按钮后,Silverlight应根据该设置进行一些计算 在计算过程中,大量使用反射(并且是必要的)来获取字符串属性的值。最后,计算分数并将其写入整数字段。这需要为13000个对象中的每一个对象执行 目前,作为一个临时解决方案,我使用一个头脑风暴:如何在Silverlight中实现背景计算?,silverlight,background,Silverlight,Background,我目前正在开发一个Silverlight 4.0应用程序,它在da DataGrid控件中显示大约13.000行。单个项包含大约40个字符串属性和一个整数属性 在包含该网格的页面上有一个面板,用户可以在其中设置不同的权重。单击“更新”按钮后,Silverlight应根据该设置进行一些计算 在计算过程中,大量使用反射(并且是必要的)来获取字符串属性的值。最后,计算分数并将其写入整数字段。这需要为13000个对象中的每一个对象执行 目前,作为一个临时解决方案,我使用一个BackgroundWorke
BackgroundWorker
实例和Grids Dispatcher(进入UI线程并允许访问网格的ItemsSource属性),迭代每个项目并计算分数。
这个过程大约需要3分钟,而且太长了,因为用户不想等待超过几秒钟。不幸的是,Silverlight 4中没有包含PLinq&Co,甚至我尝试实现多线程解决方案也失败了,因为我需要返回到UI线程(->Dispatcher)来更新每个元素(实现INotifyPropertyChanged
,并将其转发到网格)和访问ItemsSource。因此,即使在使用半并行解决方案时,由于依赖于UI线程,速度也不是很快
除了显示数据之外,用户还需要能够过滤默认情况下不支持的数据。因此,我创建了一个类似的类,它实现了ICollectionView
接口
你有什么想法或建议我可以试试吗
提前谢谢 我的建议是不要在有问题的对象上使用
INotifyPropertyChanged
,或者使用ObservableCollection
。而是使用一个简单的类来表示一行,并使用普通的oldList
来保存集合。使用CollectionViewSource
对象作为DataGrid.ItemsSource
并让其处理排序
重新计算时,请先尝试此操作。切换到后台线程。创建一个新的列表
将其容量初始化为与当前填充的列表
计数相同的容量。枚举当前的列表
以执行重新计算,然后添加到新的列表
。处理完所有内容后,切换到UI线程,只需将新的列表
分配给CollectionViewSource.Source
属性
我怀疑这一变化将使事情变得足够快,而无需对列表进行任何并行处理。然而,如果你觉得有帮助的话,包含一些并行处理应该太难了。这种方法的最大优点是,UI只有在完成所有操作后才会更新。你是对的,它非常快(我没有想到,如果不使用任何并行处理,它可能会那么快)。谢谢!:)