Я пишу сложный запрос Reactive Extensions с большим количеством операторов. Как я могу узнать, что происходит?
Я спрашиваю и отвечаю на это, поскольку он подходит к честной битке и, вероятно, хорошо используется.
Я пишу сложный запрос Reactive Extensions с большим количеством операторов. Как я могу узнать, что происходит?
Я спрашиваю и отвечаю на это, поскольку он подходит к честной битке и, вероятно, хорошо используется.
Вы можете добавить эту функцию к вашим операторам Rx, пока вы их разрабатываете, чтобы увидеть, что происходит:
public static IObservable<T> Spy<T>(this IObservable<T> source, string opName = null)
{
opName = opName ?? "IObservable";
Console.WriteLine("{0}: Observable obtained on Thread: {1}",
opName,
Thread.CurrentThread.ManagedThreadId);
return Observable.Create<T>(obs =>
{
Console.WriteLine("{0}: Subscribed to on Thread: {1}",
opName,
Thread.CurrentThread.ManagedThreadId);
try
{
var subscription = source
.Do(x => Console.WriteLine("{0}: OnNext({1}) on Thread: {2}",
opName,
x,
Thread.CurrentThread.ManagedThreadId),
ex => Console.WriteLine("{0}: OnError({1}) on Thread: {2}",
opName,
ex,
Thread.CurrentThread.ManagedThreadId),
() => Console.WriteLine("{0}: OnCompleted() on Thread: {1}",
opName,
Thread.CurrentThread.ManagedThreadId)
)
.Subscribe(obs);
return new CompositeDisposable(
subscription,
Disposable.Create(() => Console.WriteLine(
"{0}: Cleaned up on Thread: {1}",
opName,
Thread.CurrentThread.ManagedThreadId)));
}
finally
{
Console.WriteLine("{0}: Subscription completed.", opName);
}
});
}
Здесь пример использования показывает тонкую разницу в поведении Range
:
Observable.Range(0, 1).Spy("Range").Subscribe();
Выдает вывод:
Range: Observable obtained on Thread: 7
Range: Subscribed to on Thread: 7
Range: Subscription completed.
Range: OnNext(0) on Thread: 7
Range: OnCompleted() on Thread: 7
Range: Cleaned up on Thread: 7
Но это:
Observable.Range(0, 1, Scheduler.Immediate).Spy("Range").Subscribe();
Выдает вывод:
Range: Observable obtained on Thread: 7
Range: Subscribed to on Thread: 7
Range: OnNext(0) on Thread: 7
Range: OnCompleted() on Thread: 7
Range: Subscription completed.
Range: Cleaned up on Thread: 7
Определите разницу?
Очевидно, вы можете изменить это, чтобы записывать в журналы или в Debug, или использовать директивы препроцессора, чтобы сделать постную сквозную подписку на сборку выпуска и т.д....
Вы можете применить Spy
всю цепочку операторов. например:.
Observable.Range(0,3).Spy("Range")
.Scan((acc, i) => acc + i).Spy("Scan").Subscribe();
Выдает вывод:
Range: Observable obtained on Thread: 7
Scan: Observable obtained on Thread: 7
Scan: Subscribed to on Thread: 7
Range: Subscribed to on Thread: 7
Range: Subscription completed.
Scan: Subscription completed.
Range: OnNext(1) on Thread: 7
Scan: OnNext(1) on Thread: 7
Range: OnNext(2) on Thread: 7
Scan: OnNext(3) on Thread: 7
Range: OnCompleted() on Thread: 7
Scan: OnCompleted() on Thread: 7
Range: Cleaned up on Thread: 7
Scan: Cleaned up on Thread: 7
Я уверен, что вы можете найти способы обогащения этого в соответствии с вашими целями.