Rx Observable只能使用一次吗?

时间:2015-05-07 14:34:43

标签: vb.net system.reactive

我有以下代码,它是从Web Api调用的。正如您所见,我希望尽快返回并将工作转移到线程池上。 (客户端轮询以查看作业何时完成。但轮询与此无关。这些例程的目的只是提取数据并在后台写入文件,同时保持作业在表格中的进度。客户端将询问此信息以确定文件是否已准备就绪,因此我不会尝试将进度消息推送到客户端。)

Public Function Extract(filepath as string, ...) as ExtractResult

    dim source = ExtractInternal(filepath, ...)
    ' works first time it is called only!
    using source.SubscribeOn(ThreadPoolScheduler.Instance)
                .SubScribe()
    end using

    ' works every time it is called ...
    dim subscription = source.SubscribeOn(ThreadPoolScheduler.Instance)
                             .SubScribe()

    Return New ExtractResult()
End Function

Public Function ExtractInternal(filepath as string, ...) as IObservable(of Unit)
    return Observable.Create(of Unit)
         Function()
             ....
             uses filepath here 

             Return Disposable.Empty
         End Function
End Function

正如您在我的评论中所看到的,如果我使用自动处理使用...,我发现第一次调用observable但之后没有调用。然而,如果我将订阅分配给本地var,那么每次Web调用调用例程时它都会起作用,但我担心我实际上会留下任何东西。

有人可以解释为什么observable不能在后续调用中重新实例化,也许可以解释为什么我每次都可以让它工作并在之后整理好。

编辑:

所以我最终使用了Observable.Defer,这似乎汤姆给了我我想要的东西......

Public Function Extract(filepath as string, ...) As ExtractResult

    Observable.Defer(Function() ExtractInternal(filepath, ...) _
              .SubscribeOn(NewThreadScheduler.Default) _
              .Subscribe()

    Return New ExtractResult()

End Function

我想知道这是否是正确的方法,可以在使用当前参数值的同时给予我适当的处理。

有人可以确认或更正吗?

编辑2

那是错的!事实上,如果我将其重写为

Public Function Extract(filepath as string, ...) As ExtractResult

    Using Observable.Defer(Function() ExtractInternal(filepath, ...)  
                    .SubscribeOn(NewThreadScheduler.Default) _
                    .Subscribe()
    End Using

    Return New ExtractResult()

End Function

我得到了与我在撰写帖子时最初获得的相同的行为。

有一件事(在众多中)我不明白为什么如果observable是局部var,当第二次调用Extract方法时,另一个observable没有被创建并订阅?如果我真的在引擎盖下引用相同的observable,它似乎违背了作用域逻辑?我显然误解了。

很多thx

取值

1 个答案:

答案 0 :(得分:0)

是的,当您处置订阅时,它会停止接收通知。 您应该将它保存在实例字段中,并让类实现一次性。这类消费者可以在方便的时候处理它。

Dispose实施中,您拨打subscription.Dispose()