protected virtual async Task <List <T> > GetBatchOf100(List <Dictionary <string, AttributeValue> > modelKeyBatch) { var table = new T().GetTable(); var fullAds = new List <T>(); var fullAdBatchKeys = new Dictionary <string, KeysAndAttributes> { { table, new KeysAndAttributes { Keys = modelKeyBatch } } }; const int MAX_ATTEMPTS = 4; int currentAttempt = 0; BatchGetItemResponse response; do { currentAttempt += 1; var responseTask = Client.BatchGetItemAsync(fullAdBatchKeys).ConfigureAwait(false); response = await responseTask; fullAds.AddRange(response .Responses[table] .Select(x => JsonConvert.DeserializeObject <T>(Document.FromAttributeMap(x).ToJson()))); if (response.UnprocessedKeys.Any()) { var waitTime = ExponentialBackoff.GetWaitTime(currentAttempt, TimeSpan.FromSeconds(10), TimeSpan.FromMinutes(1)); Logging.Log($"Read capacity exceeded. Failed to get {response.UnprocessedKeys[table].Keys.Count} records. " + $"Attempt {currentAttempt} of {MAX_ATTEMPTS}. Retrying in {waitTime.TotalSeconds} seconds."); new Sleeper(Logging).Sleep(waitTime); } } while (response.UnprocessedKeys.Any() && currentAttempt < MAX_ATTEMPTS); if (currentAttempt == MAX_ATTEMPTS) { throw new Exception($"Failed to read all items after {MAX_ATTEMPTS} attempts."); } return(fullAds); }