我对此问题有一个特定的场景,但一个好的通用解决方案应该适用于很多情况:
我有一个WPF ItemsControl,其项目的IsSelected属性是绑定到视图模型中相应属性的数据。然后,我有一个计算密集的例程,在所选项目上运行(在后台线程上)。问题是,如果我在更改项目的IsSelected属性时触发计算密集型任务,那么当同时选择多个项目时,计算密集型任务每个项目选择运行一次,而不是仅仅一次已经选择了这些项目,这是它需要做的所有事情,因此它最终会占用比实际需要更多的处理器时间。
IEnumerable<MyObject> items;
...
void IsSelectedPropertyChangedListener(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "IsSelected")
DoSomeIntensiveCalculation(items.Where(t=>t.IsSelected));
}
void DoSomeIntensiveCalculation(IEnumerable<MyObject> itemsToCalculate)
{
...
}
当然我可以注册ItemsControl的SelectionChanged事件并触发它,因为即使选择了多个项目,每次选择更改只调用一次,但这有点违反MVVM,还有其他情况一个通用的解决方案可以适用,这将不会有这么简单的工作。 (如果你有一个很好的论据,为什么在这种特殊情况下我应该这样做,因为它比任何替代方案都好,我愿意听)
我能想到的另一个例子可能是你有一个ObservableCollection,你想在每次改变时计算一些困难。当然你会注册CollectionChanged事件来触发你的计算,但是假设有些东西一下子就把大量的项目添加到集合中,你真的只需要在添加所有项目后进行一次计算,添加的每个项目都会大大降低性能。
如果另一个实例已经开始运行,我可以阻止密集型任务运行,只需设置一个标志,使其在完成时再运行一次,即使选择了一堆东西,也会导致它只运行两次一下子,但这仍然是真正必要的一次。
每次启动新任务时,我都可以杀死已经运行的任务实例,但这需要在计算任务中添加大量代码,以便在请求时优雅地自行停止。它也不适用于密集型任务无法控制的情况(即它位于第三方库中,并且没有提供优雅的停止机制)。
答案 0 :(得分:0)
不是100%肯定你在问什么,但这里有一些想法: