/
dOJer113
/
Insect
Обзор
Документация
Войти
/
dOJer113
/
Insect
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
lab_5
UI/InsectGenerator.cs
146 строк
5 KB
aleks
lab 5
14 дек 2025, 19:32
14 дек 2025, 19:32
395af5a
Код
Авторство
О чём код?
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; using System.Threading.Tasks; using insects; using insects.Factory; using ProgressOverlayWindow; namespace UI; /// <summary> /// Генератор данных насекомых с поддержкой прогресса и пейсинга. /// </summary> public static class InsectGenerator { private const int TotalCount = 1_000_000; private const int ChunkSize = 2_500; private static readonly TimeSpan MinDuration = TimeSpan.FromSeconds(30); private static readonly TimeSpan MaxDuration = TimeSpan.FromSeconds(60); /// <summary> /// Генерирует коллекцию насекомых. /// </summary> /// <param name="parFactory">Выбранная фабрика для создания экземпляров.</param> /// <param name="parProgress">Окно прогресса.</param> /// <param name="parToken">Токен отмены.</param> /// <returns>Список сгенерированных насекомых.</returns> public static async Task<List<AbstractInsect>> GenerateAsync( IFactory parFactory, IProgressOverlayWindow parProgress, CancellationToken parToken) { var random = new Random(); var result = new List<AbstractInsect>(TotalCount); parProgress.Initialize("Генерация насекомых", "Создание тестовой выборки", "Подготовка генератора", TotalCount); var stopwatch = Stopwatch.StartNew(); var produced = 0; while (produced < TotalCount) { parToken.ThrowIfCancellationRequested(); var chunk = Math.Min(ChunkSize, TotalCount - produced); for (var i = 0; i < chunk; i++) { var insect = CreateRandomInsect(parFactory, random); result.Add(insect); } produced += chunk; parProgress.NextStep(chunk, $"Создано {produced:N0} из {TotalCount:N0}"); await ApplyPacingAsync(stopwatch, produced, parToken); } await EnsureMinimumDurationAsync(stopwatch, parToken); parProgress.Close(); return result; } private static async Task ApplyPacingAsync(Stopwatch parStopwatch, int parProduced, CancellationToken parToken) { var expected = MinDuration.TotalMilliseconds * (parProduced / (double)TotalCount); var elapsed = parStopwatch.Elapsed.TotalMilliseconds; var budget = MaxDuration.TotalMilliseconds - elapsed; var delay = Math.Min(Math.Max(expected - elapsed, 0), Math.Max(budget, 0)); if (delay > 1) { await Task.Delay(TimeSpan.FromMilliseconds(delay), parToken); } } private static async Task EnsureMinimumDurationAsync(Stopwatch parStopwatch, CancellationToken parToken) { var elapsed = parStopwatch.Elapsed; if (elapsed < MinDuration) { var remaining = MinDuration - elapsed; if (parStopwatch.Elapsed + remaining > MaxDuration) { remaining = MaxDuration - parStopwatch.Elapsed; } if (remaining > TimeSpan.Zero) { await Task.Delay(remaining, parToken); } } } private static AbstractInsect CreateRandomInsect(IFactory parFactory, Random parRandom) { var makeButterfly = parRandom.Next(0, 2) == 0; AbstractInsect insect = makeButterfly ? parFactory.CreateButterfly() : parFactory.CreateBeetle(); FillCommonFields(insect, parRandom); switch (insect) { case GlassCover glassCover: glassCover.WingsTransparencyDegree = parRandom.Next(15, 100); glassCover.ProboscisLength = $"{parRandom.Next(3, 18)} mm"; break; case Monarch monarch: monarch.ProboscisLength = $"{parRandom.Next(2, 20)} mm"; monarch.MigrationRange = parRandom.Next(800, 5500); break; case Ladybug ladybug: ladybug.MandibleSize = Math.Round((decimal)parRandom.NextDouble() * 12 + 1, 2); ladybug.NumberOfSpots = parRandom.Next(2, 25); break; case Necrophages necrophages: necrophages.MandibleSize = Math.Round((decimal)parRandom.NextDouble() * 9 + 1, 2); necrophages.StageOfSuccession = parRandom.Next(1, 6); break; case Beetle beetle: beetle.MandibleSize = Math.Round((decimal)parRandom.NextDouble() * 10 + 1, 2); break; case Butterfly butterfly: butterfly.ProboscisLength = $"{parRandom.Next(2, 18)} mm"; break; } return insect; } private static void FillCommonFields(AbstractInsect parInsect, Random parRandom) { parInsect.BodySize = Math.Round((decimal)parRandom.NextDouble() * 72 + 5, 2); parInsect.HasWings = parRandom.Next(0, 3) != 0; parInsect.MouthpieceType = BuildMouthpiece(parRandom); } private static string BuildMouthpiece(Random parRandom) { const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var length = parRandom.Next(4, 12); var characters = Enumerable.Range(0, length) .Select(_ => parRandom.Next(0, 4) == 0 ? parRandom.Next(0, 10).ToString() : alphabet[parRandom.Next(alphabet.Length)].ToString()); return string.Join(string.Empty, characters); } }