为什么没有订阅重载只需要一个错误处理程序?

时间:2013-02-16 00:33:05

标签: c# exception-handling system.reactive

IObservable的订阅重载次数为Next,Next + Error,Next + Complete,Next + Complete + Error,但为什么单独的错误没有可观察到的?

我认为这是因为可能存在异常的IObservable并且会引起冲突,即:

IObservable<Exception> obs;
obs.Subscribe(ex => { });

RX不知道你是订阅了Next还是Error。

有没有办法单独订阅错误而不创建一个空的完整代表?

obs.Subscribe(
    o => { },
    ex =>
    {
        // error-handling-code
    });

2 个答案:

答案 0 :(得分:6)

好的,这似乎是一个智力问题,所以:

从c#编译器的角度来看,对于IObservable方法签名,你提出的是(考虑到T = Exception):

public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext);
public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onError);

两种方法重载都具有相同的签名,编译器不支持它。

从接口角度来看,IObserver定义如下:

public interface IObserver<in T>
{
    void OnCompleted();
    void OnError(Exception error);
    void OnNext(T value);
}

接口的实现者必须是这样的:

public class Observer<T> : IObserver<T>
{
    public void OnCompleted()
    {
    }

    public void OnError(Exception error)
    {
        // Do something with exception
    }

    public void OnNext(T value)
    {
    }
}

所以,即使你没有指定OnNext =()=&gt; {},底层基础设施必须实现它。你不会失去指定它的任何表现。

从观察者模式的逻辑角度来看,您的意图是异步订阅元素/事件序列。省略OnNext函数并仅保留OnError的方法签名会对Rx库的用户产生误导。如果你明确表明你不想做任何OnNext的事情,那就更清楚了。

  

收到OnCompleted或OnError方法后,Rx   语法保证可以认为订阅   结束。

您尝试做的事情相当于制作空的foreach循环并等待异常:

try
{
    foreach (var e in sequence)
    {
        // do nothing
    }
}
catch (Exception ex)
{
    // Do something
}

这不常见。

答案 1 :(得分:1)

我认为这是你忽略的:

  

收到OnCompletedOnError方法后,Rx   语法保证订阅可以被认为是   完成

  1. 如果您只关心将终止操作的异常 try-catch就是你所需要的。
  2. 如果您关心异常序列,则必须抓住它们 使用observer.OnNext(ex)返回,而不是使用observer.OnError中断订阅。