如何处理行为主题的异常

时间:2013-08-02 10:53:14

标签: c# exception system.reactive behaviorsubject

我有行为主题

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

Skip是为了避免重复行为主题上的最后一个错误,但唉它不会那样工作。跳过不会跳过错误,只会跳过有效数据,因此行为主题中当前状态的错误会不断发生。

是否有一种聪明的编写Skip的方法,也会跳过错误。有些东西告诉我这是不可能的,但希望我错了

1 个答案:

答案 0 :(得分:2)

由于问题的前提是错误的,我使用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;

将生成一个Exceptional持有值“xxxzzz”。如果任何步骤确实抛出异常,那么它将短路并仅保留异常。

我的实施基于另一个SO答案是https://gist.github.com/bradphelan/6154972