4

IObservableには、Next、Next + Error、Next + Complete、Next + Complete + Errorのサブスクライブオーバーロードがありますが、エラーだけでオブザーバブルがないのはなぜですか?

IObservable of Exceptionが存在する可能性があり、競合が発生する可能性があるためだと思います。

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

RXは、NextまたはErrorをサブスクライブしているかどうかを知りません。

空の完全なデリゲートを作成せずに、エラーだけをサブスクライブする方法はありますか?

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

2 に答える 2

6

OK、これは知的な質問のようです。

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 = () => {} を指定しなくても、基盤となるインフラストラクチャで実装する必要があります。それを指定してパフォーマンスを失うことはありません。

オブザーバー パターンの論理的な観点から、あなたの意図は要素/イベントのシーケンスに非同期的にサブスクライブすることです。OnNext 関数を省略して OnError のみを残すメソッド シグネチャは、Rx ライブラリのユーザーにとって誤解を招く可能性があります。OnNext で何もしたくないという意図を明示的に述べると、より明確になります。

OnCompleted または OnError メソッドが受信されると、Rx 文法により、サブスクリプションが終了したと見なされることが保証されます。

あなたがやろうとしていることは、空の foreach ループを作成して例外を待つことと同じです:

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

これは一般的なシナリオではありません。

于 2013-02-16T11:51:51.747 に答える
1

私はこれがあなたが見落としているものだと思います:

OnCompletedorOnErrorメソッドが受信されると、Rx文法は、サブスクリプションが終了したと見なすことができることを保証します

  1. 操作を終了する例外だけを気にする場合は、try-catchが必要です。
  2. 例外のシーケンスが気になる場合は、でobserver.OnNext(ex)サブスクリプションを中断しないように、例外をキャッチして、を使用して戻る必要がありますobserver.OnError
于 2013-02-16T01:23:11.413 に答える