2012-11-09 33 views
1

IObservable.Do()已經過載與OnError處理程序,但異常傳播到Subscribe()呼叫,但如果Subscribe指定OnError - 異常不會傳播給調用者 - 在這裏是簡單的例子:在DO()爲什麼的OnError行爲)和訂閱(在.NET RX不同

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); 
    } 

回答

1

簡短的回答的問題是:Do監視器通知; Subscribe處理它們。

其中一個引發而不是另一個的實際原因是對於沒有提供的訂閱調用的默認OnError處理程序是拋出異常。因此,無論Do的存在如何,第一個方法都會拋出,第二個方法不會因爲傳遞給Subscribe的OnError處理程序而拋出。

Do是作爲一個開球運算符提供的,它允許您在通知被用戶觀察或發送給運營商的管道之前對其進行一些處理。它最常見的用途是用於調試或記錄。除了傳遞給Do的方法的副作用之外,您應該看到系統的行爲在有或沒有Do之間沒有區別。

如果您有:

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

obs.Subscribe(...); 

你會看到相同的一系列通知將傳遞給Subscribe方法。如果Do沒有通過例外,它將修改通知流,這與該運營商的設計相反。

+0

感謝您的澄清。你可以評論這個問題http://stackoverflow.com/q/13310865/296494 PLZ,如果我理解正確'.Do()'鏈不是最好的選擇那裏。 –

相關問題