2010-02-12 8 views
6

내 클라이언트 클래스에서 Faulted() 이벤트를 처리 중이므로 원격 서비스에서 예외가 발생하고 채널에 오류가 발생해도 정상적으로 종료 할 수 있습니다.System.ServiceModel.Diagnostics.CallbackException이란 무엇이며 처리 할 수없는 이유는 무엇입니까?

protected void RemoteDataRetriever_Faulted(object sender, EventArgs e) 
{ 
    (sender as ICommunicationObject).Abort(); 
    this.Dispose(); 
    throw new ChannelTerminatedException("The remote service threw an unhandled exception and as a result the channel has been closed."); 
} 

그래서 내가 무엇을 기대하는 것은 클라이언트가 내가 수동으로 던져 한 ChannelTerminatedException를 처리하고 대신 내 예외가 System.ServiceModel.Diagnostics.CallbackException에 싸여지고 등 사용자에게 메시지를 보낼 수 있다는 것입니다 : 여기에 내 코드입니다. 알았어 괜찮아. CallbackException은 ServiceModel 라이브러리에 존재하지 않으며 제 단위 테스트에 좋지 않은 일반 Exception을 제외하고는 처리 할 방법이없는 것처럼 보입니다. 도대체 무슨 일이 벌어지고있는거야? 어떻게 든 그것을 무력화시키고 내가 원했던 예외를 던질 수 있습니까?

+0

직접 예외를 던지고 있기 때문에 포장되지 않은 다른 예외를 사용할 수 있습니까? 나는 당신이 그 밑에 WCF를 사용하고 있다는 사실을 드러내지 않는 무언가를 생각하고 있습니다 ... –

+0

주사위가 없습니다. 나는 ChannelTerminatedException을 StackOverflowException으로 변경했다. 그리고 그것은 여전히 ​​성가신 CallbackException으로 감싸고있다. (던지면 내부 예외가된다.) "사용자 콜백에서 예외가 발생했습니다. 예외 스택과 내부 예외를 확인하여 실패한 콜백을 확인하십시오."라는 성가신 메시지가 나타납니다. 예, 콜백이 예외를 던졌습니다. 나는 그것을 던진 사람이었다! 더 많은 연구를하고 WCF 플래그/매개 변수가 어딘가에 있는지 확인하여이 동작을 사용하지 않도록 설정할 것입니다. –

답변

4

밝혀 짐에 따라 System.ServiceModel.Diagnostics.CallbackException은 "% SystemRoot % \ Microsoft.net \ Framework \ v3.0 \ Windows Communication Foundation \ SMDiagnostics.dll"이라는 작은 알려진 어셈블리 안에 내부 클래스가 채워져 있으며 내부 자체 만 포함되어 있습니다 수업. 글쎄, 그건 우리가 절대로 그 예외를 잡을 수 없다는 것을 의미하기 때문에 악취를 낸다. 그러나 위의 예외 (System.ServiceModel.Diagnostics.ExceptionUtility.ThrowHelperCallback (Exception innerException))를 인스턴스화하는 클래스/메서드를 찾아서 CommunicationObject 내부의 가상 메서드 OnFaulted()에서 호출하고 있음을 발견했습니다. 따라서 이론적으로 CommunicationObject에서 파생 된 모든 클래스 (미안 ClientBase<T>)는 해당 메서드를 재정의하고 ThrowHelperCallback()을 호출하지 말라고 할 수 있습니다. 즉, 실행 가능한 후보자는 ChannelFactoryBase<T>에서 파생 된 클래스입니다. 이론적으로 나는 성가신 CallbackException을 억제하는 내 자신의 커스텀 채널 팩토리를 구현할 수 있었지만, 지금은 너무 많은 작업을해야만 할 것이다.

EDIT : @Jeremy - 전 와이어를 통해 SOAP 봉투를 검사하면 예상대로 일반 오류가 발생하는 것으로 나타났습니다. 이는 CallbackException이 직렬화되지 않아 생성되지 않음을 나타냅니다. 서버.

<s:Body> 
    <s:Fault> 
     <s:Code> 
      <s:Value>s:Receiver</s:Value> 
      <s:Subcode> 
       <s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value> 
      </s:Subcode> 
     </s:Code> 
     <s:Reason> 
      <s:Text xml:lang="en-US">The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the &lt;serviceDebug&gt; configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.</s:Text> 
     </s:Reason> 
    </s:Fault> 
</s:Body> 
+0

호스트에서 반환 된 처리되지 않은 예외에 대한 응답으로 클라이언트에서 CallbackException이 생성되었음을 명확히하지 못했습니다. 내 요점은 일반 오류가 서버 측에서 처리되어야하므로 클라이언트 (다른 ​​언어로 다른 사람이 작성한 것일 수 있음)가 필요 없기 때문입니다. –

+0

답장을 +1하십시오.답장에서 FaultContracts를 사용하여 가장 일반적인 예외를 클라이언트 측에서 정상적으로 처리 할 수 ​​있지만 더 심각하고 예기치 않은 예외는 Faulted 이벤트에서 이상적으로 처리됩니다. 그렇기 때문에 나는 MS가 그들에게 내부 클래스에 던져 넣으려고하는 예외를 훔친다는 것에 조금 화가 나있다. 그러나 소수의 MS 프레임 워크를 위해 개발 한 결과 이제는 이것이 과정에 대한 단순한 결과라는 것을 알게되었습니다. –

+0

예외를 처리하는 방법은 모두 다른 방식을 사용하는 것 중 하나입니다. 그러나 예외를 throw하는 메서드를 재정의하려는 경우에도 액세스 할 수없는 예외를 throw하는 것은 이치에 맞지 않습니다. 최소한 공개 형식으로 포장하면 처리 할 수 ​​있습니다. –

2

서버에서 예외가 발생하고 있으므로 System.ServiceModel.Diagnostics.CallbackException이 표시됩니다. 예외가 클라이언트 응용 프로그램의 도메인 외부에서 발생하기 때문에 클라이언트가 액세스 할 수없는 유형 일 수 있습니다. 콜백 메커니즘은보고있는 CallbackException을 생성하여이를 처리합니다. 이는 정적 멤버에 액세스 할 때 처리되지 않은 예외가 발생할 때 throw되는 System.TypeInitializationException과 유사합니다. 이것을 정상적으로 처리하려고하면 서버 측에서 예외를 처리하고 소켓을 닫으면 처리 할 수있는 클라이언트에서 예외가 트리거됩니다.

+0

올바르지 않습니다. 내 대답을 보라. –

+0

나는 그것이 다소 모호했다고 생각하는 방식으로 생각한다. 나는 그 대답을 조금 더 명확하게 편집했다. –

관련 문제