2009-08-11 7 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

Iは、チャネルのWaitForRequest方法を見直すことにより、CPUの負荷を減らすことができます。したがって、TryReceiveRequest呼び出しは正常に完了します。ただし、ServiceModelはTryReceiveRequestをスパムしています。多少の時間のために何も読むことがなければ、接続を閉じる可能性はありますか? – Etan

+0

Closeを手動で呼び出しても、ServiceModelがBeginTryReceiveRequestを呼び出すのを停止しませんでした。動作を停止する唯一の方法は、私の問題の正しい解決策ではないように思われるAbort()を手動で呼び出すことでした。 – Etan

答えて

0

だから、誰かがまだこの問題を解決する必要があるかもしれません。 BeginTryReceiveRequestとEndTryReceiveRequest でチャンネルのプロパティを確認してください。

.....

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); 
      } 
関連する問題