GroupBy然后ObserveOn丢失物品

时间:2011-06-13 15:42:55

标签: multithreading group-by system.reactive

在LinqPad中试试这个:

Observable
    .Range(0, 10)
    .GroupBy(x => x % 3)
    .ObserveOn(Scheduler.NewThread)
    .SelectMany(g => g.Select(x => g.Key + " " + x))
    .Dump()

结果显然是不确定的,但在每种情况下我都无法收到所有10个项目。我目前的理论是,当管道编组到新线程时,项目正在通过分组的observable进行观察。

2 个答案:

答案 0 :(得分:1)

Linqpad不知道你正在运行所有这些线程 - 它立即到达代码的末尾(记住,Rx语句并不总是同步行动,这就是想法!),等待几毫秒,然后通过吹走AppDomain及其所有线程(尚未赶上)来结束。尝试在末尾添加一个Thread.Sleep,以便让新线程有时间赶上。

顺便说一句,Scheduler.NewThread是一个非常低效的调度程序,EventLoopScheduler(完全创建一个线程)或Scheduler.TaskPool(使用TPL池,就好像你为每个项目创建了一个Task )效率更高(当然在这种情况下,因为你只有10个项目,Scheduler.Immediate是最好的!)

答案 1 :(得分:0)

这里看来问题在于在GroupBy操作中开始订阅新组与实现新订阅的延迟之间的时间。如果将迭代次数从10增加到100,则应该在一段时间后开始看到一些结果。

此外,如果您将GroupBy更改为.Where(x => x%3 == 0),您可能会注意到没有值丢失,因为对IObservable组的动态订阅不需要初始化new观察者。