Лучший способ поймать исключение WCF в Silverlight? - PullRequest
14 голосов
/ 18 сентября 2008

У меня есть приложение Silverlight 2, которое использует службу WCF. Как таковой, он использует асинхронные обратные вызовы для всех вызовов методов службы. Если служба не работает, или она выходит из строя, или сеть отключается и т. Д. До или во время одного из этих вызовов, генерируется исключение, как и следовало ожидать. Проблема в том, что я не знаю, как поймать это исключение.

  • Поскольку это асинхронный вызов, я не могу заключить мой начальный вызов в блок try / catch и заставить его выбрать исключение, которое происходит после того, как программа перешла из этой точки.

  • Поскольку прокси-сервер службы генерируется автоматически, я не могу поместить блок try / catch в каждую сгенерированную функцию, которая вызывает EndInvoke (где на самом деле отображается исключение). Эти сгенерированные функции также окружены внешним кодом в стеке вызовов, поэтому в стеке больше нигде не помещается попытка / отлов.

  • Я не могу добавить try / catch в мои функции обратного вызова, потому что исключение происходит до того, как они будут вызваны.

  • В моем файле App.xaml.cs есть функция Application_UnhandledException, которая фиксирует все необработанные исключения. Я мог бы использовать это, но это кажется грязным способом сделать это. Я бы предпочел зарезервировать эту функцию для действительно неожиданных ошибок (или ошибок) и не заканчивать с кодом в этой функции для каждого обстоятельства, с которым я хотел бы иметь дело определенным образом.

Я упускаю очевидное решение? Или я застрял с помощью Application_UnhandledException?

[Изменить]
Как упомянуто ниже, свойство Error - это именно то, что я искал. Что бросает меня в тупик, так это то, что исключение выдается и кажется необработанным, но выполнение может продолжаться. Это вызывает событие Application_UnhandledException и заставляет VS2008 прервать выполнение, но продолжение в отладчике позволяет продолжить выполнение. Это на самом деле не проблема, просто кажется странным.

Ответы [ 9 ]

12 голосов
/ 18 сентября 2008

Я проверяю свойство Error в аргументах события в обработчике события завершенного метода сервиса. У меня не было проблем с тем, что обработчик событий не вызывается. В случае, когда сервер отключается, вызов занимает несколько секунд, а затем возвращается с ProtocolException в свойстве Error.

Предполагая, что вы попробовали это, и ваш обратный вызов действительно никогда не вызывается, вы можете посмотреть на настройку сгенерированного прокси-класса. См. эту статью .

5 голосов
/ 19 сентября 2008

Я нашел ветку форума , в которой говорилось об этом, и в ней упоминается, что рекомендуется использовать свойство Error. Между этой темой и моим собственным опытом я могу сделать следующие выводы:

  • В обычном коде .NET сгенерированный прокси-класс правильно обрабатывает исключение, помещая исключение в свойство Error вместо его выброса.

  • В Silverlight сгенерированный прокси-класс устанавливает свойство Error, но не обрабатывает исключение полностью. Исключение подобрано отладчиком, который открывает окно исключения с сообщением «ProtocolException не было обработано кодом пользователя». Несмотря на это сообщение, исключение, по-видимому, на самом деле не передается функции Application_UnhandledException.

Я ожидаю, что это одна из вещей, которые они исправят в финальной версии.

Пока что я буду использовать свойство Error и просто займусь выполнением прерывания отладчика. Если это становится слишком раздражающим, я могу отключить разрыв на исключение для ProtocolException.

0 голосов
/ 24 августа 2012

Чтобы справиться с этой ситуацией, используйте TargetInvocationException. Это будет ловить исключение, когда сеть не работает или ваша служба недоступна.

0 голосов
/ 03 июня 2011

С XNA на WP7 я обнаружил, что у меня не было выбора, кроме как вручную добавить try / catch к различным асинхронным методам End * FunctionName * (); ничто иное, что я пробовал, не предотвратило бы сбой и завершение работы приложения, когда сервер был недоступен. Очень сложно вручную обновить этот код при изменении службы.

Я удивлен, что это не большая проблема, поскольку, похоже, нет другого способа отловить эти исключения в WP7 с использованием XNA, но я полагаю, это просто говорит о том, сколько (== не так много) людей пытаясь сделать это, чем что-либо еще. Если бы они просто заставили slsvcutil.exe генерировать методы синхронизации, мы могли бы легко перехватить их в нашем собственном рабочем потоке, но, к сожалению, сгенерированный код использует потоки пула потоков без каких-либо средств для отлова исключений.

0 голосов
/ 24 мая 2011

Использование собственного генератора прокси WCF является хорошим решением для обработки асинхронных исключений в Silver-light.Click здесь для загрузки исходного кода.

0 голосов
/ 26 марта 2010

В Silverlight 3 отладчик Visual Studio перехватывает эти исключения, так что обработчик исключений - до смешного - никогда не достигается. Однако при запуске без отладчика обработчик исключений вызывается, как и ожидалось. Я думаю, это нормально, пока кто-то знает об этом. Я признаю, что потратил впустую несколько часов, пытаясь понять, как углубиться во внутреннюю работу Silverlight / Wcf / Browser, чтобы получить мое исключение Не ходи туда.

0 голосов
/ 06 июня 2009

Я не сантехник, поэтому я решил создать свой собственный класс обслуживания WCF, который переопределяет некоторые функциональные возможности файла класса "reference.cs", автоматически генерируемого Visual Studio, затем я добавил свою собственную попытку ловить блоки, чтобы ловить ошибки связи.

Класс, который я создал, выглядит примерно так:

public class myWCFService : MyWCFServiceClient
{

    protected override MyController.MyService.IMyWCFService CreateChannel()
    {
        return new MyWCFServiceClientChannel(this);
    }

}

private class MyWCFServiceClientChannel : ChannelBase<MyController.MyService.IMyWCFService>, MyController.MyService.IMyWCFService
{
    /// <summary>
    /// Channel Constructor
    /// </summary>
    /// <param name="client"></param>
    public MyWCFServiceClientChannel(System.ServiceModel.ClientBase<MyController.MyService.IMyWCFService> client) :
    base(client)
    {
    }
    /// <summary>
    /// Begin Call To RegisterUser
    /// </summary>
    /// <param name="memberInformation"></param>
    /// <param name="callback"></param>
    /// <param name="asyncState"></param>
    /// <returns></returns>
    public System.IAsyncResult BeginRegisterUser(MyDataEntities.MembershipInformation memberInformation, System.AsyncCallback callback, object asyncState)
    {               
        object[] _args = new object[1];
        _args[0] = memberInformation;
        System.IAsyncResult _result = base.BeginInvoke("RegisterUser", _args, callback, asyncState);
        return _result;               
    }
    /// <summary>
    /// Result from RegisterUser
    /// </summary>
    /// <param name="result"></param>
    /// <returns></returns>
    public MyDataEntities.MembershipInformation EndRegisterUser(System.IAsyncResult result)
    {
        try
        {
            object[] _args = new object[0];
            MyDataEntities.MembershipInformation _result = ((MyDataEntities.MembershipInformation)(base.EndInvoke("RegisterUser", _args, result)));
            return _result;
        }
         catch (Exception ex)
        {
            MyDataEntities.MembershipInformation _result = new MyDataEntities.MembershipInformation();
            _result.ValidationInformation.HasErrors = true;
            _result.ValidationInformation.Message = ex.Message;
            return _result;
        }
    }
}
0 голосов
/ 12 марта 2009

OOpps ....

Извините, неправильный ответ с моей стороны (ну, парень из MSFT не нажал, обратные вызовы службы записи ответа вызываются в том же потоке пользовательского интерфейса), дело в

Подробнее:

- In development even detaching from the debugger, this method is never reached. 
- On the production environment yes.

Мне кажется, что-то связано с параметрами Visual Studio и перехватом исключений.

Подробнее, в этой теме http://silverlight.net/forums/p/48613/186745.aspx#186745

Довольно интересная тема.

0 голосов
/ 12 марта 2009

Вы можете забыть о Application_UnhandledException при обратных вызовах асинхронных клиентов, причина:

Application_UnhandledException только исключения, сгенерированные в потоке пользовательского интерфейса, могут быть перехвачены Application.UnhandledExceptions

Это означает, что ... вообще не вызывается для асинхронного вызова WCF: -).

Проверьте подробный ответ от MSFT

http://silverlight.net/forums/t/21828.aspx

Здравствуйте, Application.UnhandledExceptions может перехватывать только исключения, созданные в потоке пользовательского интерфейса. Он не может перехватывать исключения из других потоков. Вы можете попробовать это, чтобы устранить проблему: в Visual Studio в меню «Отладка» выберите «Исключения». Затем отметьте «Общие исключения во время выполнения». Это приведет к остановке отладчика при возникновении исключения. Но учтите, что иногда это может раздражать, даже если исключение уже обнаружено. Вы можете использовать флажки для фильтрации исключений, которые вы хотите перехватить.

В моем случае хорошей новостью является то, что обработки сообщения об ошибке только при обратном вызове службы clietn достаточно, если вы не выполняете отладку.

Спасибо

Braulio
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...