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 是否存在,第二个方法不会因为传递给订阅的 OnError 处理程序。

Do 是作为 teeing 运算符提供的,它允许您在通知被订阅者观察或发送到运算符的管道之前对通知进行一些处理。它最常见的用途是调试或记录。除了传递给 Do 的方法的副作用之外,您应该看到使用或不使用 Do 的系统行为之间没有区别

如果你有:

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

obs.Subscribe(...);

您将在传递给的方法中看到相同系列的通知Subscribe。如果 Do 没有传递异常,它将修改通知流,这与该运算符的设计背道而驰。

于 2012-11-09T17:37:35.980 回答