Этот тип T может быть любым из моих конкретный класс, который хранит возвращаемое целое число из базы данных.
Я заставил его работать, но в настоящее время он принимает только определенный IEnumerable. Как сделать так, чтобы я мог передавать любой IEnumerableлюбому из моих классов?
А также как обрабатывать результат в OnRetry? Поскольку он должен иметь доступ к параметру IEnumerable, который в каждом классе называется по-разному.
Код: Выделить всё
public static async ValueTask KeepTrying(Func func, int expectedInteger) where TResult : IEnumerable
{
var pipeline = new ResiliencePipelineBuilder()
.AddRetry( new RetryStrategyOptions(){
ShouldHandle = new PredicateBuilder().Handle()
.HandleResult(result => result.First().MyInteger != expectedInteger),
MaxRetryAttempts = 3,
Delay = TimeSpan.FromSeconds(2)
})
.Build();
return await pipeline.ExecuteAsync(token => new ValueTask(func()));
}
Код: Выделить всё
var result = await KeepTrying(() => DB.MyFunction(), expectedInteger: 100);
- Без надлежащего контекст, я не могу сказать, когда генерируется NotFoundException. Но по обоснованному предположению, он выдается тогда, когда в противном случае функция базы данных вернула бы ноль. Но пустая и пустая коллекция — это не одно и то же.
Код: Выделить всё
if (result.Count == 0)
throw new NotFoundException("Some error");
return result;
- Я не уверен на 100 %, что под этим подразумевается. Не могли бы вы перефразировать это? (Что касается обработки других типов)
Иногда мне хочется вернуть из базы данных не только целое число, но и логическое значение или строку.
И что я сделал я добавил новое свойство в IMyInteger (фактически переименовал его в IReturnedValueFromDatabase, поскольку это не только int).
Код: Выделить всё
public interface IReturnedValueFromDatabase
{
public int ReturnedInteger { get; set; } // was MyInteger
public bool ReturnedBool { get; set; }
public string ReturnedString { get; set; }
}
Добавил новые параметры, допускающие значение NULL, поэтому в HandleResult я знаю, какой из них следует проверить:
Код: Выделить всё
public static async ValueTask KeepTrying(..., int? expectedNumber = null, bool? expectedBool = null, bool handleResult = true) where TResult : IReturnedValueFromDb
{
// skipping to .HandleResult()
.HandleResult(result => {
if (!handleResult)
// Sometimes I want to only handle Exception and not to check result, so added this check, but maybe there is better way?
return false;
if (expectedNumber != null)
// I am passing int so lets check int
return result.First().ReturnedInteger != expectedNumber;
if (expectedBool != null)
// I am passing bool so lets check bool
return result.First().ReturnedBool != expectedBool;
// all else fails, throw exception
throw new InvalidOperationException("Unable to determine result");
})
}
- Что касается исключения, выдаваемого функцией KeepTrying()
- использование Execute вместо ExecuteAsync
Источник: https://stackoverflow.com/questions/781 ... th-generic