Observable.Publish with rethrow behavior

时间:2016-06-21 09:40:36

标签: vb.net system.reactive reactive-programming

我有一个感冒的Observable,订阅时可能OnError。我如何创建一个冷Observable,它返回一个元素(一个接收源Observable作为依赖关系的对象),或者传播源的OnError。 使用Publish运算符,onError处理程序不会调用它。

Private Shared Sub Test()
    Dim source = Observable.Throw(Of Integer)(New Exception)
    ' Dim source = Observable.Range(0, 9)

    Dim obs = source.Publish(Function(published)
                                 Return Observable.
                                        Return(New ObjectThatConsumesXs(published))
                             End Function)

    obs.Subscribe(Sub(a)

                  End Sub,
                  Sub(ex)

                  End Sub,
                  Sub()

                  End Sub)
End Sub


Private Class ObjectThatConsumesXs
    Private _subscription As IDisposable

    Public Sub New(source As IObservable(Of Integer))
        _subscription = source.Subscribe(Sub(x)

                                         End Sub,
                                         Sub(ex)

                                         End Sub,
                                         Sub()

                                         End Sub)
    End Sub
End Class

编辑:

这将是一个很长的描述。

我的设备基本上是CAN Bus扫描仪。该设备具有串行端口,并且在接收到启动命令时,它开始镜像它在CAN总线上捕获的任何消息,直到它收到停止命令。鉴于串口波特率约为1MBaud,回复的消息包含在PPP Protocol的变体中以缓解错误。

我想设计一个连接扫描仪的桌面应用程序,向其发送命令,并接收捕获的CAN消息。它应该在ListBox / ListView中显示收到的消息,并能够实时过滤某些条件显示的内容。它还应该按照每条消息中嵌入的ID进行分组,并显示一个列有遇到的ID及其全部发生的列表。它还应显示总共不同的ID,以及消息的总数。

“开始”和“停止”命令之间收到的是表示记录的消息集合。应用程序应该能够在会话中多次记录,并且必须提供一种方法来保存磁盘上的记录以及应用的过滤器,用户定义的名称等。同一个应用程序应该能够导入这些记录以进行离线分析。

前面提到的ObjectThatConsumesXs是我的记录,它将它包含的消息公开为回复其订阅者的Observable(回复运算符)。

我正在使用ReactiveUI - MVVM / WinForms / Reactive Extensions,其中我设法设计了一个公开GetRecordUntil函数的服务,该函数返回IObservable(Of Record)。订阅后,observable会发出一条记录,该记录会使用从扫描仪收到的消息进行更新。

我对应用程序的设计提出了建议。但是,如果不重命名,我担心我的问题至少应该被重新标记。

1 个答案:

答案 0 :(得分:1)

一般情况下,我建议您不要将IObservable(Of T)作为参数传递给我们。 Observable接口为您所依赖的东西(即不了解您)提供了一种回复的方式。 但是,如果你将一个可观察的序列传递给某个东西,那么你就清楚地了解它,并且它显然希望被称为(或对刺激作出反应)。为什么不直接在事件发生时直接调用该依赖项上的方法?

无论如何,您目前的设计不会传递OnError外部序列,您只保证OnNext一个ObjectThatConsumesXs,然后完成序列。 在内部,ObjectThatConsumesXs将订阅已发布的序列,接收错误,但无法将其传播回其他代码路径。

另外请注意,您有一个名为ObjectThatConsumesXs的类型,但您可以直接在另一个方法中使用外部序列。 为什么要重复处理?

如果您可以解释您尝试做的事情(而不是您尝试解决的问题),那么我相信社区可以为您指出一个更合适的设计。