为了验证这一点,我创建了下面的方法来帮助说明事件的顺序:
public void ComplexComputation1(long i)
{
Console.WriteLine("Begin ComplexComputation1");
Thread.Sleep(100);
Console.WriteLine("End ComplexComputation1");
}
public void ComplexComputation2(long i)
{
Console.WriteLine("Begin ComplexComputation2");
Thread.Sleep(100);
Console.WriteLine("End ComplexComputation2");
}
public void FinalAction(long i)
{
Console.WriteLine("Begin FinalAction");
Thread.Sleep(100);
Console.WriteLine("End FinalAction");
}
你原来的代码跑这样的:
Begin FinalAction
Begin ComplexComputation1
Begin ComplexComputation2
End ComplexComputation2
End FinalAction
End ComplexComputation1
Begin FinalAction
Begin ComplexComputation1
Begin ComplexComputation2
End FinalAction
End ComplexComputation2
End ComplexComputation1
Begin FinalAction
Begin ComplexComputation1
Begin ComplexComputation2
End ComplexComputation2
End ComplexComputation1
End FinalAction
...
这很容易执行代码在单个后台线程上依次运行。只需使用EventLoopScheduler
即可。
var els = new EventLoopScheduler();
observable.ObserveOn(els).Subscribe(i => ComplexComputation1(i));
observable.ObserveOn(els).Subscribe(i => ComplexComputation2(i));
// next observer must be called only after ComplexComputation1/2 complete on input i
observable.ObserveOn(els).Subscribe(i => FinalAction(i));
这给:
Begin ComplexComputation1
End ComplexComputation1
Begin ComplexComputation2
End ComplexComputation2
Begin FinalAction
End FinalAction
Begin ComplexComputation1
End ComplexComputation1
Begin ComplexComputation2
End ComplexComputation2
Begin FinalAction
End FinalAction
Begin ComplexComputation1
End ComplexComputation1
Begin ComplexComputation2
End ComplexComputation2
Begin FinalAction
End FinalAction
但只要你介绍Scheduler.Default
这不起作用。
的更多或更少的简单的选择是要做到这一点:
var cc1s = observable.ObserveOn(Scheduler.Default).Select(i => { ComplexComputation1(i); return Unit.Default; });
var cc2s = observable.ObserveOn(Scheduler.Default).Select(i => { ComplexComputation2(i); return Unit.Default; });
observable.Zip(cc1s.Zip(cc2s, (cc1, cc2) => Unit.Default), (i, cc) => i).Subscribe(i => FinalAction(i));
按预期工作。
你得到一个不错的顺序是这样的:
Begin ComplexComputation1
Begin ComplexComputation2
End ComplexComputation1
End ComplexComputation2
Begin FinalAction
End FinalAction
Begin ComplexComputation2
Begin ComplexComputation1
End ComplexComputation2
End ComplexComputation1
Begin FinalAction
End FinalAction
Begin ComplexComputation1
Begin ComplexComputation2
End ComplexComputation2
End ComplexComputation1
Begin FinalAction
End FinalAction
我想过这种方法。但实际上,我不知道有多少观察者会处理每个元素。这个解决方案能应用于这种情况吗? –
我添加了序列块方法作为可能的解决方案。 –