如何从源IReactiveList中的更改触发IReactiveDerivedList重置?

时间:2016-06-17 18:53:24

标签: c# system.reactive reactiveui

我正在使用Reactive Extensions从源IReactiveDerivedList<IAmSelectable>(项目)创建ReactiveList<IAmSelectable>(selectedItems):

selectedItems = items.CreateDerivedCollection(
    c => c,
    null,
    c => c.IsSelected,
    null,
    items.Changed.Select(_ => items.Select(c => c.WhenAnyValue(x => x.IsSelected)).Merge()).Select(c => c).Switch());

其中:

public interface IAmSelectable
{
    bool IsSelected { get; set; }
}

selectedItems中任何IAmSelectable的选择状态发生变化时,我正尝试重置items。然而,当我尝试这样做时,我得到一个InvalidOperationException陈述&#34;收集被修改;枚举操作可能无法执行。&#34;这样做的正确方法是什么?

编辑:以下方法也会产生相同的例外情况:

items.ChangeTrackingEnabled = true;
selectedItems = items.CreateDerivedCollection(
    c => c,
    null,
    c => c.IsSelected,
    null,
    items.ItemChanged.Where(c => c.PropertyName == "IsSelected"));

1 个答案:

答案 0 :(得分:0)

正如查尔斯·米格所说,我正在做的其他事情导致了这个问题。具有上述代码的构造函数中的以下行是异常的原因:

service.Items.ItemsAdded.Throttle(TimeSpan.FromMilliseconds(50)).Subscribe(vm => SelectedItem = vm);

我不确定原因,但当我将其更改为:

时问题就消失了
service.Items.ItemsAdded.ObserveOn(Scheduler.Immediate).Subscribe(vm => SelectedItem = vm);

我在处理派生的反应列表时发现,收集修改的异常很难调试,特别是当调用堆栈,线程列表或者intellitrace中没有任何内容与我的代码中的任何内容相关时除了进入方法。此外,反应性派生列表的明显问题往往不是红鲱鱼 - 我通过系统地消除对CreateDerivedList的调用多次遇到这种情况,直到异常消失,才发现其他地方的问题。

我在调试此问题时学到的基本经验是:

  • 如果您在通话中使用foreach循环进行订阅,请确保您已在集合中调用ToList()进行枚举。 (这在Stack Overflow中反复说明。)
  • 如果您有任何可能与被动列表互动的选择语句,请尝试在那里调用ToList()
  • 留意潜在的时间问题;如上所述,使用不同的调度程序有时会有所帮助。

希望这些指针可以帮助别人花更少的时间来解决这类问题。