При запуске Политики Polly в приложении.NET Core она зависает после того, как перехвачено исключение
Я пытаюсь протестировать некоторый код повторной попытки Полли, который у меня есть в базовом приложении.NET Core. Я должен реализовать асинхронный метод (через унаследованный интерфейс):
public Task AddMessageAsync( ... ) { .. }
ПРИМЕЧАНИЕ: обратите внимание, что вышеописанный метод НЕ украшен async
ключевое слово? Я сделал это нарочно.
Когда я пытаюсь подключиться к сторонней службе (серверу MQ кролика), где я сделал имя хоста этой службы, неправильно / опечатка... мой код синхронизации пытается... пытается.. и не удается и выдает исключение, Большой! но после этого.... код просто виснет? Я думал, что код должен просто повторять попытки:(
private static Policy CheckRabbitMQPolicy(ILogger logger)
{
return Policy
.Handle<Exception>()
.WaitAndRetry(15, _ => TimeSpan.FromSeconds(2), (exception, timeSpan, __) => logger.LogWarning(...));
}
public Task AddMessageAsync(string content,
TimeSpan? timeToLive,
TimeSpan? initialVisibilityDelay,
CancellationToken cancellationToken)
{
CheckRabbitMQPolicy(_logger).Execute(() =>
{
using (var connection = _factory.CreateConnection())
{
.... // snipped //
}
});
return Task.CompletedTask;
}
Поэтому я подумал, что могу просто вернуть Task.CompletedTask;
потому что в этом методе нет кода, который async/await
, Но когда выдается исключение, оно обрабатывается (log.Warning(..)
вызывается / прерывается, если там есть точка останова) ... но затем зависает.
Кто-нибудь может помочь подсказать, что здесь происходит?
РЕДАКТИРОВАТЬ 1:
Согласно ответу @jeremy-thompson ниже, я подумал, что могу попробовать изменить код на:
var policyResult = CheckRabbitMQPolicy(_logger).ExecuteAndCapture(() =>
{
using (var connection = _factory.CreateConnection())
{
.... // snipped //
}
});
return policyResult.Outcome == OutcomeType.Successful
? Task.CompletedTask
: Task.FromException(policyResult.FinalException);
Так что тогда - пытается подключиться к плохому серверу - не удается и выдает исключение - сейчас выходит из ExecuteAndCapture() (не возвращается еще 14 раз...)
- возвращает Task.FromException
...
так что... немного ближе... но все равно не повторяю еще 14 раз...
1 ответ
Вы всегда должны стараться представить минимальный рабочий пример в вопросе, который демонстрирует проблему, с которой вы сталкиваетесь. Я взял ваш код и попытался сделать его работающим примером, но все, кажется, работает как положено. Он удаляется 14 раз и не зависает, как вы описываете.
Возможно, упрощая ваш код подобным образом, вы сможете выяснить, что не так в вашем случае. Удачи!
class Program
{
static void Main()
{
var msg = new MyMessageClass();
msg.AddMessageAsync("content", TimeSpan.MaxValue, TimeSpan.MaxValue, new CancellationToken());
}
}
class MyMessageClass
{
readonly ILogger _logger = NLog.LogManager.GetCurrentClassLogger();
private static Policy CheckRabbitMQPolicy(ILogger logger)
{
return Policy
.Handle<Exception>()
.WaitAndRetry(14, _ => TimeSpan.FromSeconds(2),
(exception, timeSpan, __) =>
{
logger.Warn(exception.Message);
});
}
public Task AddMessageAsync(string content,
TimeSpan? timeToLive,
TimeSpan? initialVisibilityDelay,
CancellationToken cancellationToken)
{
var policyResult = CheckRabbitMQPolicy(_logger).ExecuteAndCapture(() => throw new Exception("Connection error"));
return policyResult.Outcome == OutcomeType.Successful
? Task.CompletedTask
: Task.FromException(policyResult.FinalException);
}
}