2009-08-11 4 views
0

추가 소스에서 HTTP 메시지를 수신 할 수 있도록 사용자 지정 바인딩을 만들었습니다. 그러나 아직 버그가 없습니다.TryReceiveRequest가 무한 시간 호출 됨

첫 번째 요청이 처리되고 더 많은 요청이 들어 오면 서비스가 느려지고 느려지 자마자 내 서비스가 최대 100 % CPU 사용을 밀어내는 것을 관찰했습니다.이 동작은 로깅을 삽입 한 후에 볼 수 있습니다 바인딩의 모든 단일 기능에 명령. 첫 번째 요청이 도달하기 전에

는 모든 작동까지 :

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 인터페이스를 구현, 그래서해야 :

ChannelListener: OnBeginAcceptChannel 
ChannelListener: OnAcceptChannel 

그런 다음, 첫 번째 메시지의 처리가 이루어집니다 요청을 받고 회신 한 다음 채널을 닫을 수 있어야합니다. 채널을 닫는 대신 ServiceModel은 이미 과거에 사용 된 채널에 상관없이 TryReceiveRequest를 이미 사용 된 채널에 스팸으로 유지합니다.

이 문제를 올바르게 해결할 수있는 방법이 있습니까? 채널이 사용 된 후에도 채널을 열어 두는 것은 쓸모가 없지만 ServiceModel은 응답 컨텍스트를 닫은 후에 채널을 닫지 않는 이유는 무엇입니까?

+0

나는 채널의 WaitForRequest 방법을 수정하여 CPU의 부하를 줄일 수 있습니다. 따라서 TryReceiveRequest 호출이 제대로 완료됩니다. 그러나 ServiceModel은 TryReceiveRequest를 스팸으로 유지합니다. 일정 시간 동안 아무 것도 읽지 않으면 연결을 종료 할 수 있습니까? – Etan

+0

Close를 수동으로 호출해도 ServiceModel이 BeginTryReceiveRequest를 호출하는 것이 중지되지 않았습니다. 문제를 해결할 수있는 유일한 방법은 Abort()를 직접 호출하여 내 문제에 대한 올바른 해결책이 아닌 것 같습니다. – Etan

답변

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); 
      }