2012-09-14 3 views
0

그래서 nettcpbinding을 통해 WCF 서비스를 호출하는 콘솔 응용 프로그램을 작성하고 있습니다. 비즈니스는 시간 제한 값으로 사용할 값을 지정할 수 있기를 원합니다. 원래 작업 시간 제한을 시도했지만 무시당하는 것처럼 보였습니다. 그래서 다른 값을 시도했습니다. 그 중 하나의 작품 (또는 조합) :WCF 서비스에 대한 시간 초과 구현 C# console app

나는 시간이 초과되면 채널을 닫을 수 있었으면 좋겠다.하지만 마침내 블럭에 넣으면 그 시간이 끝날 때까지 잠깐 앉아있다. 반면 나는 초 단위로 시간 제한 값을 설정하고 있습니다. 서버 측 코드에 지연을 추가하여 테스트하고 있습니다. 잠시 시간을내어 시뮬레이트합니다.

닫기를 첫 번째 try 블록으로 옮길 수는 있지만 채널을 열어 두는 것이 걱정됩니다. 그런 다음 사용자에게 시간 초과 오류를 훨씬 빨리보고합니다. 또는 스레딩을 구현해야합니까?

public static String ExecuteSearch(List<KeyValuePair<string, string>> paramItems) 
{ 
    var context = GetAdminContext(); 
    var parsedParameters = ParseParameters((paramItems)); 

    //TODO: Figure out how to implement timeout - & workout if port number will be passed in?? 
    IPartyProfile partyProfile = null; 

    long start = System.Environment.TickCount; 

    using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint")) 
    { 
     EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName)); 
     IPartyController proxy = factory.CreateChannel(address); 

     if (proxy != null) 
     { 
      var timeoutTimeSpan = new TimeSpan(0, 0, parsedParameters.TimeOut); 
      ((IContextChannel)proxy).OperationTimeout = timeoutTimeSpan; 
      factory.Endpoint.Binding.SendTimeout = timeoutTimeSpan; 
      factory.Endpoint.Binding.ReceiveTimeout = timeoutTimeSpan; 
      factory.Endpoint.Binding.OpenTimeout = timeoutTimeSpan; 
      factory.Endpoint.Binding.CloseTimeout = timeoutTimeSpan; 

      try 
      { 
       // TODO: potentially call something more complex 
       partyProfile = proxy.GetLatestPartyProfile(context, parsedParameters.PartyId); 

      } 
      catch (EndpointNotFoundException ex) 
      { 
       throw new Exception(STATUS_UNKNOWN + ": Endpoint specified not responding", ex); 
      } 
      catch (TimeoutException ex) 
      { 
       throw new Exception(STATUS_UNKNOWN + ": Timeout exceeded", ex); 
      } 
      finally 
      { 
       try 
       { 
        ((IClientChannel)proxy).Close(); 
       } 
       catch (Exception) 
       { 
       } 

      } 
     } 
    } 

    long stop = System.Environment.TickCount; 
    long elapsed = (stop - start)/1000; // in seconds 

    return SetResultMessage(elapsed, partyProfile, parsedParameters); 
} 

편집 - 난() 빨리 그것을 종료 factory.Abort를 사용할 수 있다고 생각합니다. (위 코드에 Close가있는 곳을 적어 두었습니다).

+0

그래서 시간 제한을 설정하는 순서를 변경 했으므로 SendTimeout 값을 지정하면 확인 된 것 같습니다. 마지막으로 내 시도 잡기에 - 채널이 열려 있는지 확인하고 만약 그렇다면 - 공장을 중단하고 가까이 전화하십시오. 더 이상 영원히 걸리지 않는 것 같습니다. – Jen

답변

1

설명에서 SendTimeout은 조정할 값입니다 (this question on various timeouts 참조). 기본적으로 1 분이지만 더 적은 값 (예 : 5 초)으로 변경하면 proxy.GetLatestPartyProfile을 호출하면 5 초 후에 실제로 TimeoutException이 발생합니다 (서비스 호출이 응답 할 것보다 많다고 가정 할 경우). 현재 내가 문제를 일으킬 수있는 적어도 하나의 일을 볼 수 게시 된 코드에서

: 당신이 후 공장 에 시간 제한 값을 설정하는 당신은 이미 프록시를 만들었습니다. 관련 서술문의 순서를 바꾸고 다시 시도하십시오. 이런 식으로 뭔가 :

using (ChannelFactory<IPartyController> factory = new ChannelFactory<IPartyController>("IPartyControllerEndpoint")) 
{ 
    var timeoutTimeSpan = new TimeSpan(0, 0, parsedParameters.TimeOut); 
    factory.Endpoint.Binding.SendTimeout = timeoutTimeSpan; 

    EndpointAddress address = new EndpointAddress(String.Format("net.tcp://{0}/ServiceInterface/PartyController.svc", parsedParameters.HostName)); 
    IPartyController proxy = factory.CreateChannel(address); 

    if (proxy != null) 
    { 
     try 
     { 
      // TODO: potentially call something more complex 
      partyProfile = proxy.GetLatestPartyProfile(context, parsedParameters.PartyId); 
     } 
     // etc. 

참고 : 나는 현재의 과부하 voor CreateChannel이 바인딩에 사용하는 것을 완전히 확실하지 않다. 이전에 설정 한 바인딩을 사용하는 것이 타당한 것처럼 보이지만 여전히 문제가있는 경우 CreateChannel(Binding, EndpointAddress) 과부하를 사용하여 실험 할 수 있습니다.

+0

감사합니다 - 그것을 밖으로 시도합니다 :) – Jen