Zmniejszenie powielonego kodu obsługi błędów w C #?
Nigdy nie byłem w pełni zadowolony z tego, jak działa obsługa wyjątków, jest wiele wyjątków i try / catch przynosi do tabeli (rozwijanie stosu itp.), Ale wydaje się, że w tym procesie łamie się dużo modelu OO.
W każdym razie jest problem:
Powiedzmy, że masz jakąś klasę, która zawija lub zawiera operacje we / wy pliku sieciowego (np. Odczyt i zapis do jakiegoś pliku na jakiejś konkretnej ścieżce UNC). Z różnych powodów nie chcesz, aby te operacje we / wy zakończyły się niepowodzeniem, więc jeśli wykryjesz, że zawiodły, spróbuj ponownie, a będziesz je ponawiał, dopóki nie uda im się osiągnąć limitu czasu. Mam już wygodną klasę RetryTimer, którą mogę utworzyć instancję i użyć do uśpienia bieżącego wątku między ponownymi próbami i określenia, kiedy upłynął limit czasu itd.
Problem polega na tym, że masz kilka operacji we / wy w kilku metodach tej klasy i musisz zawinąć każdą z nich w logikę try-catch / retry.
Oto przykładowy fragment kodu:
RetryTimer fileIORetryTimer = new RetryTimer(TimeSpan.FromHours(10));
bool success = false;
while (!success)
{
try
{
// do some file IO which may succeed or fail
success = true;
}
catch (IOException e)
{
if (fileIORetryTimer.HasExceededRetryTimeout)
{
throw e;
}
fileIORetryTimer.SleepUntilNextRetry();
}
}
Jak więc uniknąć duplikowania większości tego kodu dla każdej operacji we / wy pliku w całej klasie? Moim rozwiązaniem było użycie anonimowych bloków delegatów i jednej metody w klasie, która wykonała przekazany blok delegatów. Dzięki temu mogłem robić takie rzeczy w innych metodach:
this.RetryFileIO( delegate()
{
// some code block
} );
Lubię to nieco, ale pozostawia wiele do życzenia. Chciałbym usłyszeć, jak inni ludzie rozwiązaliby ten problem.