我有一个行为主题

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/

10-12 15:54