只是对流为什么没有到达catch块感到困惑。我知道,每当发生异常时,都会调用OnError
方法,但调用ToObservable
时不应该发生异常吗?只有在处理第三个数字(0)时,才会发生异常。我完全被说服了。
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");
}
Linq是延迟求值的,这意味着在调用Subscribe()
之前不会求值,这就是为什么您的catch块没有命中
在Selector中引发与OnError'ing不同。某些运算符(如Start)会将代码包装在try/catch中并封送至OnError,但大多数运算符不会。想象一下,如果每个LINQ Select都包含在一个try/catch中!这会很慢。您的OnNext订阅也是如此。
如果你想创建一个确实有这种行为的Select版本,这里有一种方法:
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);
}
});
}