为什么在的OnError DO(行为)和订阅()的不同之处.NET RX [英] Why OnError behaviour in Do() and Subscribe() differs in .NET RX

查看:195
本文介绍了为什么在的OnError DO(行为)和订阅()的不同之处.NET RX的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

IObservable.Do()具有过载与的OnError 处理,但异常被传播给订阅()呼叫,但如果的OnError 指定订阅 - 异常不传播给调用者 - 在这里是一个简单的例子:

 公共静态无效的主要()
    {
        OnErrorInDo(); //抛出
        OnErrorInSubscribe(); //不抛出
    }
    公共无效OnErrorInDo()
    {
        。变种observableThatThrows = GetEnumerableThatThrows()ToObservable();
        VAR解析度= observableThatThrows.Do(I => Console.Write({0},I),LogEx).Subscribe();
    }
    公共无效OnErrorInSubscribe()
    {
        。变种observableThatThrows = GetEnumerableThatThrows()ToObservable();
        VAR解析度= observableThatThrows.Do(I => Console.Write({0},I),LogEx)
            .Subscribe(ⅰ=> {},LogEx);
    }

    公开的IEnumerable< INT> GetEnumerableThatThrows()
    {
        的foreach(在Enumerable.Range变种I(0,10))
        {
            如果(ⅰ!= 5)
                得到回报我;
            其他
                抛出新的异常(EX在枚举);
        }
    }
    公共无效LogEx(例外前)
    {
        Console.WriteLine(前消息:+ ex.Message);
    }
 

解决方案

简短的回答的问题是:不要监视通知; 订阅处理它们。

之一抛出的实际原因,而不是其他的是默认的OnError处理程序调用订阅,不提供一种是抛出异常。因此,第一种方法会抛出做的presence,无论第二不会因为传递给订阅了的OnError处理程序。

做的是提供一个发球运营商,它允许你做的通知一些处理之前,它是由用户观察或向下发送运营商的管道。其最常见的用途是用于调试或记录。除了传递给执行方法的副作用,你应该看到的系统带或不带你的的行为没有什么区别。

如果您有:

  obs.Do。(I => {/ * ... * /},EX => {/ * ... * /})订阅(... );
 

  obs.Subscribe(...);
 

您将看到相同的一系列通知将传递给的方法订阅。如果你的未通过异常时,它会被修改的通知的流,这是违背该操作者的设计

IObservable.Do() has overload with OnError handler but exception is propagated to Subscribe() call, but if OnError is specified in Subscribe - exception is not propagated to the caller - here is the simple example:

    public static void Main()
    {
        OnErrorInDo(); // throws
        OnErrorInSubscribe(); // doesn't throw
    }        
    public void OnErrorInDo()
    {
        var observableThatThrows = GetEnumerableThatThrows().ToObservable();
        var res = observableThatThrows.Do(i => Console.Write("{0}, ", i), LogEx).Subscribe();
    }
    public void OnErrorInSubscribe()
    {
        var observableThatThrows = GetEnumerableThatThrows().ToObservable();
        var res = observableThatThrows.Do(i => Console.Write("{0}, ", i), LogEx)
            .Subscribe(i=>{}, LogEx);
    }

    public IEnumerable<int> GetEnumerableThatThrows()
    {
        foreach (var i in Enumerable.Range(0,10))
        {
            if (i != 5)
                yield return i;
            else
                throw new Exception("ex in enumerable"); 
        }
    }
    public void LogEx(Exception ex)
    {
        Console.WriteLine("Ex message:" + ex.Message);
    } 

解决方案

The short answer to the question is: Do monitors notifications; Subscribe handles them.

The actual reason one throws and not the other is that the default OnError handler for calls to Subscribe that do not provide one is to throw the exception. As such, the first method will throw, regardless of the presence of Do and the second will not because of the OnError handlers passed to Subscribe.

Do is provided as a teeing operator which allows you to do some processing with the notification before it is observed by subscribers or sent down the pipeline of operators. Its most common uses are for debugging or logging. Aside from the side-effects of the methods passed to Do, you should see no difference between the behavior of the system with or without Do.

If you have:

obs.Do(i => { /* ... */ }, ex => { /* ... */ }).Subscribe(...);

and

obs.Subscribe(...);

You will see the same series of notifications into the methods passed to Subscribe. If Do did not pass the exceptions on, it would be modifying the stream of notifications, which it is counter to the design of that operator.

这篇关于为什么在的OnError DO(行为)和订阅()的不同之处.NET RX的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆