2017-06-06 30 views
3

我是RX的新手,一直在研究错误处理和Retry的使用;我有以下内容(是的,我知道这不是一个'真正的'单元测试,但它让我可以摆弄!),并想知道如何去保持重试但能够记录任何异常?RX.Net:使用重试但记录任何异常

[Test] 
    public void Test() 
    { 
     var scheduler = new TestScheduler(); 

     var source = scheduler.CreateHotObservable(
      new Recorded<Notification<long>>(10000000, Notification.CreateOnNext(0L)), 
      new Recorded<Notification<long>>(20000000, Notification.CreateOnNext(1L)), 
      new Recorded<Notification<long>>(30000000, Notification.CreateOnNext(2L)), 
      new Recorded<Notification<long>>(30000001, Notification.CreateOnError<long>(new Exception("Fail"))), 
      new Recorded<Notification<long>>(40000000, Notification.CreateOnNext(3L)), 
      new Recorded<Notification<long>>(40000000, Notification.CreateOnCompleted<long>()) 
     ); 

     source.Retry().Subscribe(
      l => Console.WriteLine($"OnNext {l}"), 
      exception => Console.WriteLine(exception.ToString()), // Would be logging this in production 
      () => Console.WriteLine("OnCompleted")); 

     scheduler.Start(
      () => source, 
      0, 
      TimeSpan.FromSeconds(1).Ticks, 
      TimeSpan.FromSeconds(5).Ticks); 
    } 

导致...

OnNext 0 
OnNext 1 
OnNext 2 
OnNext 3 
OnCompleted 

...这正是我想要离开的事实发生,我想记录发生2和3之间

异常

有没有办法允许订阅者在OnError中看到异常(并记录下来),然后重新订阅,以便看到3?

Thx!

回答

4

你可以实现与此:

source 
    .Do(_ => { }, exception => Console.WriteLine(exception.ToString()),() => {}) 
    .Retry() 
    .Subscribe(
     l => Console.WriteLine($"OnNext {l}"), 
     //  exception => Console.WriteLine(exception.ToString()), // Would be logging this in production 
     () => Console.WriteLine("OnCompleted") 
    ); 

只是为了澄清这是怎么回事就在这里:OnError是终止信号。如果错误达到了订阅,那会终止流的其余部分。 .Retry终止订阅,吞下OnError,然后重新订阅,将两个订阅合并在一起。例如看看这个:

source 
    .StartWith(-1) 
    .Retry() 
    .Subscribe(
     l => Console.WriteLine($"OnNext {l}"), 
     () => Console.WriteLine("OnCompleted") 
    ); 

你的产出将是

OnNext -1 
OnNext 0 
OnNext 1 
OnNext 2 
OnNext -1 
OnNext 3 
OnCompleted 

OnNext -1显示了两次,因为它表明,每当您订阅(该OnError

之后Retry贵。测试可观察性是一个不好的测试,它打破了“Rx合约”,即通知遵循以下模式:

OnNext* (OnCompleted | OnError)? 

也就是说,0或更多OnNext通知,然后是可选OnError或可选OnCompleted。任何类型的通知都不应跟随OnErrorOnCompleted

+0

关于不良测试;试图让一个简单的例子一起失败的结果! :-(谢谢你的澄清,我还没有完全意识到Retry是如何运作的 – inthegarden

+0

我在我的应用程序中实际上有的是从FromEventPattern驱动的热观测值,我收到一个包含byte []的事件,然后解密byte [],建立消息类型并相应地进行反序列化;在Observer.OnNext中,我根据这个消息执行一个动作,我不希望发生的是流的终止,如果我在这些操作中有任何问题解密/序列化等)我只是想记录失败并继续处理,这是可能的吗? – inthegarden

+0

“我不想发生的是为流终止”应该是“我不想要的“ – inthegarden