2016-08-04 99 views
2

我目前正在開發一個REST服務,其中一種方法是長時間運行的任務(名爲CalculatePrimeOneWay)。它的定義是WCF REST服務和狀態輪詢

[OperationContract(IsOneWay = true)] 
[WebInvoke(Method = "POST", UriTemplate = "primeoneway/{jobnumber}")] 
void CalculatePrimeOneWay(string jobnumber, Prime prime); 

由於不存在與REST服務沒有回調的能力,我認爲有關實現一種輪詢方法來獲取狀態信息。此輪詢方法定義爲

[OperationContract] 
    [WebGet(UriTemplate = "poll/{jobnumber}")] 
    Job GetJobStatus(string jobnumber); 

我將狀態信息寫入MS SQL表。

我啓動我的客戶端並調用CalculatePrimeOneWay方法。隨後對GetJobStatus的調用返回帶有協議錯誤,狀態碼400和狀態描述錯誤請求的WebException。 但是,如果CalculatePrimeOneWay完成,然後我調用GetJobStatus,所有工作都很好。

爲什麼我無法在CalculatePrimeOneWay仍在運行時調用GetJobStatus? 對於長時間運行任務和輪詢機制的情況,還有哪些其他解決方案可能?

感謝

+1

_「我的長時間運行任務和輪詢機制的場景有什麼其他解決方案?」 - 您是否嘗試搜索?讓一個HTTP調用的持續時間超過幾毫秒從來都不是一個好主意。 – CodeCaster

+1

我沒有搜索互聯網,我發現的唯一可能的想法是這種輪詢機制。由於長時間運行的方法被定義爲OneWay,所以HTTP調用本身完成得非常快,我也可以在我的日誌中看到。 –

+0

你在使用per-session/singleton實例嗎?或者您是否重新使用客戶頻道?或兩者? –

回答

0

你得到可能是一個或兩個的兩件事情的結果的行爲:

  1. 您與運行服務每個會話或者單實例存儲
  2. 你是重複使用相同的客戶端通道進行輪詢呼叫,就像您進行單向呼叫一樣。

您應該將該服務配置爲按呼叫實例化並在新客戶端通道實例上進行輪詢呼叫。

我現在已經明確定義了服務PerCall。對於每個來自 的調用,客戶端都會獲得一個新的HttpWebRequest對象,並且在調用之後,我將關閉Web響應對象 。該行爲仍然是相同的

OK嘗試更換

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] 

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, 
       ConcurrencyMode = ConcurrencyMode.Multiple, 
       UseSynchronizationContext = false)] 

我使用IIS表達出我的VisualStudio

確定的 - 的原因你得到這種行爲我因爲您使用的是使用cassini Web服務器的Visual Studio。這在處理請求時不支持併發。查看帖子herehere

嘗試在控制檯應用程序中臨時託管服務,此問題將得到解決。

+0

我現在明確定義了服務PerCall。對於來自客戶端的每次調用,我都會得到一個新的HttpWebRequest對象,並在調用之後關閉Web響應對象。行爲仍然是一樣的。 –

+0

@WalterTaus我剛更新了我的文章。 –

+0

我已經如上所述定義了ServiceBehavior。此外,我將服務分成兩個完全獨立的服務。 OneWay方法在其中。在另一個端口上,第二個服務具有輪詢功能。結果仍然是一樣的。只有在OneWay方法完成其任務時才進行輪詢。當我在OneWay方法的執行過程中嘗試進行輪詢時,出現WebException並且我的OneWay方法停止工作。我從VisualStudio中使用IIS Express。 –