2015-05-07 53 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它不會是正確的 - 會嗎? (只是爲了包含一個參數而改變了示例) –