NoP*_*God 4 c# exception-handling system.reactive
IObservable的订阅重载为Next,Next + Error,Next + Complete,Next + Complete + Error,但为什么单独只有Errors没有可观察到的?
我认为这是因为可能存在异常的IObservable,它会导致冲突,即:
IObservable<Exception> obs;
obs.Subscribe(ex => { });
Run Code Online (Sandbox Code Playgroud)
RX不知道您是否订阅了Next或Error.
有没有一种方法可以单独订阅错误而无需创建一个空的完整代表?
obs.Subscribe(
o => { },
ex =>
{
// error-handling-code
});
Run Code Online (Sandbox Code Playgroud)
好吧,这似乎是一个智力问题,所以:
从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);
Run Code Online (Sandbox Code Playgroud)
两种方法重载都具有相同的签名,并且编译器不支持它.
从接口角度来看,IObserver定义如下:
public interface IObserver<in T>
{
void OnCompleted();
void OnError(Exception error);
void OnNext(T value);
}
Run Code Online (Sandbox Code Playgroud)
接口的实现者必须是这样的:
public class Observer<T> : IObserver<T>
{
public void OnCompleted()
{
}
public void OnError(Exception error)
{
// Do something with exception
}
public void OnNext(T value)
{
}
}
Run Code Online (Sandbox Code Playgroud)
因此,即使您未指定OnNext =()=> {},底层基础结构也必须实现它.您没有松开任何指定它的性能.
从观察者模式的逻辑角度来看,您的意图是异步订阅元素/事件序列.省略OnNext函数并仅保留OnError的方法签名会对Rx库的用户产生误导.如果你明确表明你不想做任何OnNext的意图,那就更清楚了.
一旦收到OnCompleted或OnError方法,Rx语法就保证可以认为订阅已完成.
你要做的就是制作空的foreach循环并等待异常:
try
{
foreach (var e in sequence)
{
// do nothing
}
}
catch (Exception ex)
{
// Do something
}
Run Code Online (Sandbox Code Playgroud)
这不是常见的情况.