1

IObservable.Do()OnErrorハンドラーでオーバーロードされていますが、例外はSubscribe()呼び出しに伝達されますが、OnErrorで指定されている場合Subscribe- 例外は呼び出し元に伝達されません - 簡単な例を次に示します。

    public static void Main()
    {
        OnErrorInDo(); // throws
        OnErrorInSubscribe(); // doesn't throw
    }        
    public void OnErrorInDo()
    {
        var observableThatThrows = GetEnumerableThatThrows().ToObservable();
        var res = observableThatThrows.Do(i => Console.Write("{0}, ", i), LogEx).Subscribe();
    }
    public void OnErrorInSubscribe()
    {
        var observableThatThrows = GetEnumerableThatThrows().ToObservable();
        var res = observableThatThrows.Do(i => Console.Write("{0}, ", i), LogEx)
            .Subscribe(i=>{}, LogEx);
    }

    public IEnumerable<int> GetEnumerableThatThrows()
    {
        foreach (var i in Enumerable.Range(0,10))
        {
            if (i != 5)
                yield return i;
            else
                throw new Exception("ex in enumerable"); 
        }
    }
    public void LogEx(Exception ex)
    {
        Console.WriteLine("Ex message:" + ex.Message);
    } 
4

1 に答える 1

1

質問に対する簡単な答えは次のとおりDoです。通知を監視します。Subscribeそれらを処理します。

一方がスローし、もう一方がスローしない実際の理由は、一方がスローするのではなく、サブスクライブへの呼び出しのデフォルトのOnErrorハンドラーが例外をスローするためです。そのため、Doの存在に関係なく、最初のメソッドはスローされ、Subscribeに渡されたOnErrorハンドラーのために2番目のメソッドはスローされません。

Doはティーイングオペレーターとして提供されており、サブスクライバーによって監視されたり、オペレーターのパイプラインに送信されたりする前に、通知を使用して何らかの処理を行うことができます。その最も一般的な用途は、デバッグまたはロギングです。Doに渡されたメソッドの副作用を除けば、Doがある場合とない場合のシステムの動作に違いは見られないはずです。

あなたが持っている場合:

obs.Do(i => { /* ... */ }, ex => { /* ... */ }).Subscribe(...);

obs.Subscribe(...);

に渡されたメソッドに同じ一連の通知が表示されSubscribeます。Doが例外を渡さなかった場合、通知のストリームが変更され、そのオペレーターの設計に反します。

于 2012-11-09T17:37:35.980 に答える