2013-02-16 40 views
4

IObservable已订阅重载为下一个,下一个+错误,下一个+完整,下一个+完整+错误,但为什么没有可观察到只有错误?为什么没有订阅超载只需要一个错误处理程序?

我想这是因为可能有异常的的的IObservable,它可能会造成冲突,即:

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

RX不知道如果你订阅下一步或错误。

有没有办法单独订阅错误而不创建空的Complete委托?

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

根据你的相关问题,这听起来像你想观察一系列的例外,但OnError保证只给你一个......正如Nenad所说的。另外你已经接近...你需要IObservable 或主题,并使用OnNext,而不是OnError。当您的IObservable 发生异常时,OnError会失效,而不是流本身。希望有所帮助。 – 2013-02-16 12:20:18

回答

6

OK,这似乎是智力问题,所以:

从C#编译器的角度来看,为的IObservable方法签名(S),你提出这将是(考虑到T =除外):

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 = ()=> {},底层基础架构必须实现它。你不会失去指定它的任何性能。

从观察者模式的逻辑角度来看,你的意图是异步地订阅元素/事件序列。忽略OnNext函数并只保留OnError的方法签名会对Rx库的用户造成误导。更明确的是,如果您明确表明您的意图是不想在OnNext上做任何事情。

一旦OnCompleted或onError方法已被接收时,Rx 语法保证订阅可以被认为是 完成。

你正在试图做的将相当于使空foreach循环,等待例外的是什么:

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

这是不常见的场景。

+1

这有助于非常感谢。鉴于IObservable的要点是要接收一个对象流,所以当你接收这些对象时,你必须明确地指定你希望做什么* Nothing。在我的代码中,我当然会处理OnNext调用,我只想单独处理异常,在我的代码的另一个区域中,我将把多个潜在的异常源汇集在一起​​,并可能使用Amb来首先到达。然而,我现在想知道,如果IObservable 对于这个特殊用例更有意义。 – NoPyGod 2013-02-17 07:26:13

1

我觉得这是你忽略什么:

一旦OnCompletedOnError方法已被接收时,Rx 语法保证了订阅可以被认为是 完成

  1. 如果你关心只是例外,这将终止操作 的try-catch是你所需要的。
  2. 如果您关心例外情况的顺序,您必须抓住它们,并使用observer.OnNext(ex)返回 ,而不是使用observer.OnError来破坏订阅。
+0

不,我没有忽视过,我认为它甚至不相关。不,尝试抓住根本没有帮助。 – NoPyGod 2013-02-16 03:16:03

+0

通过观察,您可以异步订阅序列。在你的例子中,你根本不关心序列。大约有一个例外。你有什么合理的理由在那里使用可观察的东西吗? – Nenad 2013-02-16 10:30:01

相关问题