Обработка исключений ошибок в прокси WCF на основе событий

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

ServiceClient client = new ServiceClient(binding, endpointAddress);
client.AuthenticateCompleted += (sender, e) =>
{
    if (e.Error != null)
        throw e.Error;
};
client.AuthenticateAsync(username, password);

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

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

Также стоит упомянуть, что хотя многие из этих сбоев произошли в работающей службе с тайм-аутом открытия, закрытия, отправки и получения по 30 секунд каждый, я также пытался проверить исправления этой проблемы, сократив время ожидания до <1 секунда Я предполагаю, что это все равно будет генерировать исключения тайм-аута и не вызывать никаких других проблем, но я не уверен на 100%.

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

1 ответ

Решение

Оказывается, ошибка выдается IService.EndMethodName метод, который не доступен через класс, сгенерированный Visual Studio.

Вместо этого я решил получить доступ к каналу напрямую, чтобы иметь больше контроля над вещами. Окончательная реализация выглядит следующим образом (IService - это интерфейс, сгенерированный Visual Studio):

ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, endpointAddress);

// CreateChannel may not require any parameters outside of Mono
IService channel = factory.CreateChannel(endpointAddress);

channel.BeginAuthenticate(new AuthenticateRequest(arg0, arg1), result =>
{
    try
    {
        channel.EndAuthenticate(result);
    }
    catch(Exception ex)
    {
        throw;
    }
}, channel);

Это в простейшей форме, но общая идея заключается в том, что вызов завершается в AsyncCallback в блоке try/catch для обработки любых исключений.

Другие вопросы по тегам