0

只是爲什麼流量沒有達到捕獲塊混淆。我明白,只要發生異常,將會調用OnError方法,但在調用ToObservable時應該不會發生異常?只有在處理第三個數字(0)時纔會發生異常。我完全被困惑。爲什麼catch塊在下面的Rx代碼中沒有命中?

 static void Main() 
     { 
      try 
      { 
       var numbers = from number in 
            new int[] { 1, 2, 0, 3 } 
           select 10/number; 
       var observable = numbers.ToObservable(); 
       observable.Subscribe(OnNext, OnError, OnComplete); 
       Console.ReadKey(); 
      } 
      catch (Exception exc) 
      { 
       Console.WriteLine("Program terminated with the following message - {0}", exc.Message); 
      } 
     } 

     private static void OnNext(int i) 
     { 
      Console.WriteLine("Output : " + i); 
     } 

     private static void OnError(Exception exc) 
     { 
      Console.WriteLine("In oops : {0}", exc.Message); 
     } 

     private static void OnComplete() 
     { 
      Console.WriteLine("In done"); 
     } 
+0

爲什麼你認爲異常應立即發生? – 2012-02-11 12:36:40

+0

@JonSkeet bcoz當ToObservable被調用時它會嘗試將IEnumberable轉換爲IObservable,除以零異常會發生 – Sandbox 2012-02-11 12:39:30

回答

3

的LINQ是懶洋洋地評估,這意味着什麼的值,直到您叫Subscribe(),這就是爲什麼你的catch塊是打在選擇

+0

是的,我瞭解linq的懶惰評估。但是,ToObservable被調用時會嘗試將IEnumberable轉換爲IObservable,除以零異常將發生。但是,這並沒有發生。我對Linq和Rx的理解有點不對頭 – Sandbox 2012-02-11 12:41:55

+0

@Sandbox:ToObservable調用本身並不試圖評估序列,就我所知,它只是創建一個可記憶的觀察值序列參考,準備在有用戶時進行評估。 – 2012-02-11 13:38:22

+0

Jon是正確的,就像沒有任何事情發生,直到你Foreach一個數組(並且每個Foreach是一個新的數組運行),ToObservable()創建一個對象,當某人訂閱它時,它將通過數組運行OnNext'ing每一個項目。 – 2012-02-11 19:36:04

1

投擲是不一樣的OnError'ing。像Start這樣的某些運算符會將你的代碼封裝在try/catch中,並將其編碼爲OnError,但大多數不會。想象一下,如果每個LINQ Select都被包裝在try/catch中!它會很慢。您的OnNext訂閱也一樣。

如果你想創建一個版本選擇的是確實有這種行爲,這裏有一個辦法做到這一點:

public static IObservable<TRet> SafeSelect(this IObservable<T> This, Func<T,TRet> selector) 
{ 
    return This.SelectMany(x => { 
     try { 
      return Observable.Return(selector(x)); 
     } catch (Exception ex) { 
      return Observable.Throw<TRet>(ex); 
     } 
    }); 
} 
相關問題