private async Task <IReadOnlyCollection <T> > GetDimension <T>(string dimension, string logFileName, Func <SqlConnection, Task <IReadOnlyCollection <T> > > retrieve) { var stopwatch = Stopwatch.StartNew(); var count = _maxRetryCount; while (count > 0) { try { _jobEventSource.BeginningRetrieveDimension(dimension); IReadOnlyCollection <T> dimensions; using (var connection = await _targetDatabase.ConnectTo()) { dimensions = await retrieve(connection); } stopwatch.Stop(); _jobEventSource.FinishedRetrieveDimension(dimension, stopwatch.ElapsedMilliseconds); ApplicationInsights.TrackRetrieveDimensionDuration(dimension, stopwatch.ElapsedMilliseconds, logFileName); return(dimensions); } catch (SqlException e) { --count; if (count <= 0) { throw; } if (e.Number == 1205) { Trace.TraceWarning("Deadlock, retrying..."); ApplicationInsights.TrackSqlException("SQL Deadlock", e, logFileName, dimension); } else if (e.Number == -2) { Trace.TraceWarning("Timeout, retrying..."); ApplicationInsights.TrackSqlException("SQL Timeout", e, logFileName, dimension); } else if (e.Number == 2601) { Trace.TraceWarning("Duplicate key, retrying..."); ApplicationInsights.TrackSqlException("SQL Duplicate Key", e, logFileName, dimension); } else { throw; } Task.Delay(_retryDelay).Wait(); } catch (Exception exception) { _jobEventSource.FailedRetrieveDimension(dimension); ApplicationInsights.TrackException(exception, logFileName); if (stopwatch.IsRunning) { stopwatch.Stop(); } throw; } } return(Enumerable.Empty <T>().ToList()); }