Обработка исключений ошибок в прокси 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 для обработки любых исключений.