Чтобы проверить это, я создал следующие методы, чтобы помочь проиллюстрировать последовательность событий:
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
Я думал об этом подходе. Но на самом деле, я не знаю нескольких наблюдателей, которые обрабатывают каждый элемент. Может ли это решение применяться к такой ситуации? –
В качестве возможного решения я добавил подход блока последовательностей. –