Что такое Система. ServiceModel. Диагностика. CallbackException и почему я не могу обработать его?

В моем клиентском классе WCF я обрабатываю Faulted() событие так, чтобы, если удаленный сервис выдает исключение и дает сбой канал, я мог все еще, по крайней мере, завершить работу его корректно. Вот мой код:

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 то, что я бросил вручную и отправляю сообщение пользователю и т.д. Вместо этого мое исключение становится перенесенным в a System.ServiceModel.Diagnostics.CallbackException. Хорошо, прекрасный. Кроме вот выгода: этот CallbackException не существует в библиотеке ServiceModel и там, кажется, не способ для меня обработать ее за исключением дженерика Exception, который делает меня отрицательный результат для моих модульных тестов. Какого черта продолжается здесь? Я могу отключить это так или иначе и выдать исключение, которое я первоначально хотел?

6
задан marcgg 16 February 2010 в 16:27
поделиться

2 ответа

Как оказалось, System.ServiceModel.Diagnostics.CallbackException - это внутренний класс, помещенный в малоизвестную сборку под названием "% SystemRoot% \ Microsoft.net \ Framework \ v3.0 \ Windows Communication Foundation \ SMDiagnostics.dll ", который сам содержит только внутренние классы. Что ж, это воняет, потому что это означает, что мы никогда не сможем поймать это исключение. Однако мне удалось выследить класс / метод, который создает экземпляр указанного выше исключения (System.ServiceModel.Diagnostics.ExceptionUtility.ThrowHelperCallback (Exception innerException)), и обнаружил, что он вызывается виртуальным методом OnFaaled () внутри CommunicationObject. Таким образом, теоретически любой класс, производный от CommunicationObject (извините ClientBase ), может переопределить этот метод и запретить ему вызывать ThrowHelperCallback (). Это означает, что единственными жизнеспособными кандидатами являются классы, производные от ChannelFactoryBase . Теоретически я мог бы пойти дальше и реализовать свою собственную фабрику пользовательских каналов, которая подавляет раздражающее исключение CallbackException, но на данный момент это слишком много работы, поэтому я думаю, мне просто придется с этим разобраться.

РЕДАКТИРОВАТЬ: @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>
4
ответ дан 17 December 2019 в 02:28
поделиться

Вы видите System.ServiceModel.Diagnostics.CallbackException , потому что на сервере возникает исключение. Поскольку исключение происходит вне домена клиентского приложения, возможно, оно относится к типу, к которому у клиента нет доступа. Механизм обратного вызова обрабатывает это, создавая CallbackException, который вы видите. Это похоже на System.TypeInitializationException , которое генерируется, когда возникает необработанное исключение при доступе к статическому члену. Если вы пытаетесь справиться с этим изящно, вы можете обработать исключение на стороне сервера и закрыть сокет, что впоследствии вызовет исключение на клиенте, которое может быть обработано.

2
ответ дан 17 December 2019 в 02:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: