我有一个行为主题
var source = new BehaviorSubject<int>(0);
然后我用类似的方法处理该来源
var withErrors = source
.Select(v =>
{
if (v == 2)
{
throw new Exception("Ouch ");
}
return v;
})
我想以一种可以跳过的方式订阅withErrors
错误。尝试这样的捕获。
public IObservabe<int> SkipError(IObservable<T> source){
return source
.Catch(e=>SkipErrors(source.Skip(1));
}
然后这样称呼它
var withoutErrors = SkipError(withErrors);
跳过是为了避免在行为主题上重复最后一次的错误,但可惜这种方式不起作用。跳过不会跳过错误,而只会跳过有效数据,因此行为主体中当前状态的错误会不断得到解决。
是否有编写“跳过”的巧妙方法,它也会跳过错误。某事告诉我这是不可能的,但希望我错了
最佳答案
由于问题的前提是错误的,因此我提出了一种使用better
monad的Exceptional<T>
方法。例如
IObservable<int> source = ....;
IObservable<Exceptional<string>> withErrors =
source.Select(i=>Exceptional.Execute(()=>{
if(v==2){
throw new Exception("Ouch");
}
return v.ToString();
});
IObservable<Exception> errors =
withErrors.Where(v=>v.HasException).select(v=>v.Exception);
IObservable<string> values =
withErrors.Where(v=>!v.HasException).select(v=>v.Value);
只是为了好玩,你可以做
Exceptional<string> r =
from x in Exceptional.Execute(() => "xxx")
from y in Exceptional.Execute(() => "zzz")
select x + y;
这将生成一个异常,其值为“xxxzzz”。如果任何一个步骤确实引发异常,则它将短路并仅保留异常。
我基于另一个SO答案的实现是https://gist.github.com/bradphelan/6154972
关于c# - 如何处理行为主体的异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18015149/