Правильная обработка ошибок при вызове службы WCF - PullRequest
0 голосов
/ 17 ноября 2010

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

У меня есть интерфейс службы данных, подобный этому:

public interface IDataService

{void GetUserId (string userName, string password, Action getUserIdComplete);}

Я реализую это так:

public class MockDataService : IDataService
{
    private Action<string> _getUserIdCompleted;
    private SomeServiceClient;

    public MockDataService()
    {
        _proxy = new SomeServiceClient();
    }

    public void GetUserId(string userName, string password, Action<int> getUserIdComplete)
    {
        _getUserComplete = getUserIdComplete;

        var request = new UserRequest();
        request.UserName = userName;
        request.Password = password;
        //populate any other request info

        _proxy.GetUserIdCompleted += new EventHandler<GetUserCompletedEventArgs>(_proxy_GetUserIdCompleted);
        _proxy.GetUserIdAsync(request);
    }

    void _proxy_GetUserIdCompleted(object sender, GetUserIdCompletedEventArgs e)
    {
        _proxy.GetUserIdCompleted -= new EventHandler<GetUserCompletedEventArgs>(_proxy_GetUserIdCompleted);
        _getUserIdComplete(e.UserId);
    }
}

Моя проблема в том, что, когда происходит ошибка или время ожидания запроса, приложение завершается.Я мог бы обернуть блок try catch в вызов, но это звучит как плохая идея.

Может кто-нибудь помочь мне элегантно обработать таймауты и ошибки с помощью этого метода?

Ответы [ 2 ]

2 голосов
/ 17 ноября 2010

Насколько я знаю, перехват исключения тайм-аута - единственный способ его обработки.

Я предпочитаю использовать другой асинхронный шаблон, поскольку он обеспечивает большую гибкость в обработке исключений.Я бы пошел что-то вроде этого.

public class MockDataService : IDataService
{
    private SomeServiceChannel _channel;

    public MockDataService()
    {
        var channelFactory = new ChannelFactory<SomeServiceChannel>(
                    "CustomBinding_SomeService");
        _channel = channelFactory.CreateChannel();
        //to increase the timeout
        _channel.OperationTimeout = TimeSpan.FromMinutes(5);
    }

    public void GetUserId(string userName, string password, Action<int> getUserIdComplete)
    {
        var request = new UserRequest();
        request.UserName = userName;
        request.Password = password;
        //populate any other request info

        _proxy.GetUserIdCompleted += new EventHandler<GetUserCompletedEventArgs>(_proxy_GetUserIdCompleted);
        _proxy.GetUserIdAsync(request);
        _channel.BeginGetUserId(request, (iar) =>
           {
               try
               {
                   var result = _channel.EndGetUserId(iar);
                   getUserIdComplete(result.UserId);
               }
               catch (Exception ex)
               {
                   //handle the exception
               }
           }, null);
    }

}
1 голос
/ 17 ноября 2010

По моему очень скромному мнению, обратные вызовы в фоновых потоках (все, что является результатом асинхронных выполнений) должны всегда заключаться в обработчик исключений. Необработанные исключения в фоновых потоках убьют ваш процесс.

Теперь, это не значит, что вы должны перехватить исключение и проигнорировать его :) Просто то, что вы должны правильно его обработать, что бы это ни значило для вашего приложения. Для некоторых приложений, которые будут регистрировать их. Для других это будет где-то обновлять статус. Для других это может быть предупреждение пользователя об ошибке. Или их комбинация :)

...