2015-05-07 50 views
0

我有以下代码正在从Web Api中调用。正如你所看到的,我希望尽快返回并将工作转移到线程池。 (客户端轮询查看作业完成的时间,但轮询与此无关,这些例程的目的仅仅是提取数据并在后台编写文件,同时将作业的进度保留在表中。客户端将询问这个判断文件是否已准备好,所以我不会试图推动进度消息给客户端。)Rx Observable只能用一次?

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 

正如你可以在我的意见看,如果我使用使用自动配置...,我发现可观察者第一次被叫,但之后没有。而如果我将订阅分配给本地变量,则每次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是局部变量,当第二次调用Extract方法时,另一个observable不会被创建和订阅?如果我真的在引擎盖下引用相同的observable,它似乎违背了范围逻辑?我显然被误解了。

许多THX

小号

+0

只是一个小规则的考虑 - 每当你发现自己在做'Return Disposable.Empty'时,你可能做错了什么。 – Enigmativity

+0

@Enigmativity - Thx。是的,我觉得,但我不确定...... a)实际需要处理什么 - 解决方案是非常无状态的。b)如何构建可以发生体面/外在处理的事情。 –

+0

我需要查看代码的其余部分以确定应该在哪里。 – Enigmativity

回答

0

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

在您的Dispose实施中,您可以拨打subscription.Dispose()

+0

thx vm。我想知道是否将它作为实例变量保存,因为它在外部函数中引用了filepath参数,实例var是否将此文件路径作为闭包,因此如果其他操作使用不同的文件路径调用外部函数,如果我使用实例var它不会是正确的 - 会吗? (只是为了包含一个参数而改变了示例) –