public async Task GenerateAsync <TModel>(int recordCount, Func <int, TModel> create, Func <IEnumerable <TModel>, Task> save) where TModel : new() { _rndFormatted = new RandomFormattedString(_rnd); List <TModel> records = new List <TModel>(BatchSize); int recordNum = 0; for (int i = 0; i < recordCount; i++) { if (_cancellationToken.IsCancellationRequested) { break; } recordNum++; TModel record = create.Invoke(i); records.Add(record); if (recordNum == BatchSize) { await save.Invoke(records); records.Clear(); recordNum = 0; } } if (_cancellationToken.IsCancellationRequested) { return; } // any leftovers await save.Invoke(records); }
/// <summary> /// Generates a number of random records, checking to see if they violate a key before saving /// </summary> public async Task GenerateUniqueAsync <TModel>(IDbConnection connection, int recordCount, Action <TModel> create, Func <IDbConnection, TModel, Task <bool> > exists, Func <TModel, Task> save) where TModel : new() { _rndFormatted = new RandomFormattedString(_rnd); for (int i = 0; i < recordCount; i++) { if (_cancellationToken.IsCancellationRequested) { break; } TModel record = new TModel(); int attempts = 0; const int maxAttempts = 100; do { attempts++; if (attempts > maxAttempts) { throw new Exception($"Couldn't generate a random {typeof(TModel).Name} record after {maxAttempts} tries. Exception was thrown to prevent infinite loop."); } create.Invoke(record); } while (await exists.Invoke(connection, record)); await save.Invoke(record); } }