2017-04-22 103 views
2

假设我们有这个观察到的序列(RX)和匹配订阅:C#如何重启的RX订阅

var behaviorSubject = new BehaviorSubject<int>(3); 
var sequence = behaviorSubject.Select(x => this.webservice.Call(x)).Switch(); 
var subscription = this.sequence.Subscribe(this.Subject.OnNext, this.OnSequenceFaulted); 

序列意味着每个behaviorSubject发出一个新值的时间做一个Web服务调用的同时,取消以前的请求。如果在web服务调用期间发生异常,订阅将被终止(调用OnSequenceFaulted方法后)。

实施这样的OnSequenceFaulted方法是否是一种很好的做法?我们是否需要重新启动(重新分配)sequence以及订阅,因为异常起源于sequence内的可观察项?是否需要明确处理故障订阅?

public void OnSequenceFaulted(Exception e) 
{ 
    subscription?.Dispose(); 
    subscription = sequence.Subscribe(this.Subject.OnNext, this.OnSequenceFaulted); 
} 

回答

1

至于好的做法去真的取决于你的使用情况,你想,如果webservice.Call抛出异常发生什么。

为了解决你的问题的特定部分,虽然各地RX这里有一些很好的参考 Reactive Observable Subscription Disposal

如果观察到的完成 - 无论使用哪种OnCompleted或的OnError - 则认购已经布置给你的。这里

introtorx具有的各种错误处置技术和什么是伟大的描述可能适用于您的情况

http://www.introtorx.com/content/v1.0.10621.0/11_AdvancedErrorHandling.html

至于如何处理您的具体方案有几个选项,这里是只是一对夫妇的想法

  1. 你可以只处理webcall本身的异常,以便它不会将流转换为OnError http://www.introtorx.com/content/v1.0.10621.0/11_AdvancedErrorHandling.html#CatchSwallowingException

    var sequence = behaviorSubject.Select(x => this.webservice.Call(x) 
          .Catch((Exception exc) => 
           //do something with exception, 
           //maybe just return an empty observable and log the exception 
         ).Switch(); 
    
  2. 你也可以只告诉它重试 http://www.introtorx.com/content/v1.0.10621.0/11_AdvancedErrorHandling.html#Retry

    var subscription = this.sequence.Retry().Subscribe(this.Subject.OnNext, this.OnSequenceFaulted); 
    

有没有真正具体的Rx最佳实践AFAIK。这真的只是在发生异常时想要发生的事情。如果你不在乎,只是想让它活下来,那么重试就没有问题。如果你想捕获和记录,那么你可以把这个catch放在web服务调用上。如果你想检查异常,然后有不同的异常会导致不同的问题,你可以在Web服务调用中放入不同的catch。