2009-08-11 53 views
0

我已經構建了一個自定義綁定,可以從其他源接收HTTP消息。但是,它還沒有缺陷。TryReceiveRequest被調用無限次

我發現我的服務一旦處理第一個請求就將CPU使用率提高到100%,並且服務越來越慢,請求進來越多。插入日誌記錄後可以看到此行爲的原因命令轉換爲綁定的每個單一功能。

直到第一個請求獲取之前,一切工作正常:

ChannelListener: OnBeginAcceptChannel 
ChannelListener: OnAcceptChannel 

然後,第一條消息的處理完成:

Channel: static constructor 
Channel: constructor 
ChannelListener: OnEndAcceptChannel (completes) 
ChannelListener: Uri get 
ChannelListener: OnBeginAcceptChannel 
ChannelListener: OnAcceptChannel 
Channel: OnOpen 
Channel: BeginTryReceiveRequest 
Channel: TryReceiveRequest 
Channel: WaitForRequest 
Channel: ReceiveRequest 
Context: constructor 
Channel: EndTryReceiveRequest (completes) 
Context: RequestMessage get 
`Channel: BeginTryReceiveRequest` 
Context: Reply noTimeout 
Context: Reply 
Context: Close noTimeout 
`Channel: TryReceiveRequest` 
`Channel: WaitForRequest` 
`Channel: ReceiveRequest (hangs)` 
`Channel: EndTryReceiveRequest (doesn't complete since receive hangs)` 
`Channel: BeginTryReceiveRequest` 
`and so on...` 

通道實現IReplyChannel接口,所以它應該只有可能獲得請求,回覆並關閉頻道。 而不是僅僅關閉頻道,ServiceModel會在已使用的頻道上發送TryReceiveRequest垃圾信息,無論過去是否使用過頻道。

有什麼方法可以解決這個問題嗎?爲什麼ServiceModel在關閉回覆上下文後關閉了通道,儘管在通道消耗之後保持通道打開沒有用處?

+0

我可以通過修改信道的方法WaitForRequest降低CPU的負荷。因此,TryReceiveRequest調用正確完成。但是,ServiceModel不斷髮送垃圾郵件TryReceiveRequest。如果在某段時間內沒有任何內容需要閱讀,是否有可能關閉連接? – Etan 2009-08-12 08:17:30

+0

手動調用close並不會阻止ServiceModel調用BeginTryReceiveRequest。只有停止行爲的方法是手動調用Abort(),這似乎不是我的問題的正確解決方案。 – Etan 2009-08-12 12:17:46

回答

0

所以,也許有人仍然需要解決這個問題。檢查狀態渠道屬性BeginTryReceiveRequestEndTryReceiveRequest

.....

public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state) 
     { 
      if (State == CommunicationState.Closed) 
      { 
       return null; 
      } 
      return new TryReceiveRequestAsyncResult(timeout, this, callback, state); 
     } 

.....

public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context) 
      { 
       if (State == CommunicationState.Closed) 
       { 
        context = null; 
        return false; 
       } 
       return TryReceiveRequestAsyncResult.End(result, out context, this); 
      }