Пакет из доходности не запускается одновременно ⇐ C#
-
Anonymous
Пакет из доходности не запускается одновременно
В настоящее время я пытаюсь реализовать средство поиска файлов, которое группирует найденные файлы, чтобы их можно было обрабатывать одновременно. Но моя проблема возникает, когда она уступает, и я передаю ее задаче. Он никогда не запускает несколько задач, а ждет, пока будет выполнена предыдущая задача, прежде чем запускать следующую, причем я хочу, чтобы он запускал столько задач, сколько позволяет мой SemaphoreSlim. Я новичок в выдаче и не уверен, что проблема в выдаче, потому что она ждет, пока не завершится предыдущий итер доходности, даже если он передается в Task.Run().
public async Task RunAsync (CancellationToken cancelToken) { вар задачи = новый список(); индекс вар = 0; используя var semaphore = new SemaphoreSlim(8, 16); foreach (элементы var в FileSearcher.EnumerateFilesRecursily(@"E:/nestedAAAA", patchSize, cancelToken)) { ожидайте семафор.WaitAsync(); пытаться { Tasks.Add(StartTasksAsync(items, index, cancelToken).ContinueWith(task => { семафор.Выпуск(); задачи.Удалить(задача); })); индекс++; } поймать (исключение ex) { _logger.LogError(например, «Ошибка в HarvestEngine RunAsync»); семафор.Выпуск(); } } ждут Task.WhenAll(задачи); } частная асинхронная задача StartTasksAsync( IEnumerable элементы, внутренний индекс, Токен отмены (Token отмены) { _logger.LogInformation($"[Задача {index}] запущена..."); var DatabaseService = _serviceProvider.GetRequiredService(); вар CollectedSensitiveFiles = новый список(); foreach (элемент var в элементах) { _logger.LogInformation($"{index} нашел {item}"); } ждать Task.Delay(1000); _logger.LogInformation($"[Задача {index}] выполнена..."); } Если я увеличу Task.Delay до 10 секунд, он будет ждать 10 секунд, прежде чем начнется следующая задача, даже если Task.Delay находится внутри моего только что запущенного задачу и должен только перевести мою новую задачу в спящий режим, а не делать этого, ему придется ждать желаемое количество времени, прежде чем сможет запуститься следующая задача. поэтому, если я поставлю 1 минуту, пройдет 1 минута до следующего запуска и т. д., что на самом деле не имеет для меня смысла (за исключением случаев, когда есть какие-то уступающие вещи, о которых я не знаю).
Вот как я возвращаю найденные файлы:
внутренний статический IEnumerable EnumerateFilesRecursically( строковый каталог, int пакетный размер, Токен отмены (Token отмены) { Stack stack = новый Stack(); List currentFoundFiles = новый List(); stack.Push(каталог); пока (stack.Count > 0) { cancelToken.ThrowIfCancellationRequested(); строка currentDir = stack.Pop(); пытаться { foreach (строка subDir в Directory.GetDirectories(currentDir)) stack.Push(subDir); } поймать (UnauthorizedAccessException) { Log.Error("Поиск файлов: UnauthorizedAccessException"); } улов (DirectoryNotFoundException) { Log.Error("Поиск файлов: UnauthorizedAccessException"); } пытаться { var files = Directory.GetFiles(currentDir, "*") .Где(файл => разрешенныеРасширения.Содержит(Путь.GetExtension(файл))) .К списку(); currentFoundFiles.AddRange(файлы); } поймать (UnauthorizedAccessException) { Log.Error("Поиск файлов 2: UnauthorizedAccessException"); продолжать; } улов (DirectoryNotFoundException) { Log.Error("Поиск файлов 2: UnauthorizedAccessException"); продолжать; } если (currentFoundFiles.Count public async Task RunAsync (CancellationToken cancelToken) { вар задачи = новый список(); индекс вар = 0; используя var semaphore = new SemaphoreSlim(8, 16); foreach (элементы var в FileSearcher.EnumerateFilesRecursily(@"E:/nestedAAAA", patchSize, cancelToken)) { пытаться { задачи.Добавить(Task.Run(async () => { ожидайте Task.Yield(); _logger.LogInformation($"[Задача {index}] запущена..."); foreach (элемент var в элементах) { _logger.LogInformation($"{index} нашел {item}"); } _logger.LogInformation($"[Задача {index}] выполнена..."); }, cancelToken)); индекс++; } поймать (исключение ex) { _logger.LogError(например, «Ошибка в HarvestEngine RunAsync»); семафор.Выпуск(); } } ждут Task.WhenAll(задачи); }
В настоящее время я пытаюсь реализовать средство поиска файлов, которое группирует найденные файлы, чтобы их можно было обрабатывать одновременно. Но моя проблема возникает, когда она уступает, и я передаю ее задаче. Он никогда не запускает несколько задач, а ждет, пока будет выполнена предыдущая задача, прежде чем запускать следующую, причем я хочу, чтобы он запускал столько задач, сколько позволяет мой SemaphoreSlim. Я новичок в выдаче и не уверен, что проблема в выдаче, потому что она ждет, пока не завершится предыдущий итер доходности, даже если он передается в Task.Run().
public async Task RunAsync (CancellationToken cancelToken) { вар задачи = новый список(); индекс вар = 0; используя var semaphore = new SemaphoreSlim(8, 16); foreach (элементы var в FileSearcher.EnumerateFilesRecursily(@"E:/nestedAAAA", patchSize, cancelToken)) { ожидайте семафор.WaitAsync(); пытаться { Tasks.Add(StartTasksAsync(items, index, cancelToken).ContinueWith(task => { семафор.Выпуск(); задачи.Удалить(задача); })); индекс++; } поймать (исключение ex) { _logger.LogError(например, «Ошибка в HarvestEngine RunAsync»); семафор.Выпуск(); } } ждут Task.WhenAll(задачи); } частная асинхронная задача StartTasksAsync( IEnumerable элементы, внутренний индекс, Токен отмены (Token отмены) { _logger.LogInformation($"[Задача {index}] запущена..."); var DatabaseService = _serviceProvider.GetRequiredService(); вар CollectedSensitiveFiles = новый список(); foreach (элемент var в элементах) { _logger.LogInformation($"{index} нашел {item}"); } ждать Task.Delay(1000); _logger.LogInformation($"[Задача {index}] выполнена..."); } Если я увеличу Task.Delay до 10 секунд, он будет ждать 10 секунд, прежде чем начнется следующая задача, даже если Task.Delay находится внутри моего только что запущенного задачу и должен только перевести мою новую задачу в спящий режим, а не делать этого, ему придется ждать желаемое количество времени, прежде чем сможет запуститься следующая задача. поэтому, если я поставлю 1 минуту, пройдет 1 минута до следующего запуска и т. д., что на самом деле не имеет для меня смысла (за исключением случаев, когда есть какие-то уступающие вещи, о которых я не знаю).
Вот как я возвращаю найденные файлы:
внутренний статический IEnumerable EnumerateFilesRecursically( строковый каталог, int пакетный размер, Токен отмены (Token отмены) { Stack stack = новый Stack(); List currentFoundFiles = новый List(); stack.Push(каталог); пока (stack.Count > 0) { cancelToken.ThrowIfCancellationRequested(); строка currentDir = stack.Pop(); пытаться { foreach (строка subDir в Directory.GetDirectories(currentDir)) stack.Push(subDir); } поймать (UnauthorizedAccessException) { Log.Error("Поиск файлов: UnauthorizedAccessException"); } улов (DirectoryNotFoundException) { Log.Error("Поиск файлов: UnauthorizedAccessException"); } пытаться { var files = Directory.GetFiles(currentDir, "*") .Где(файл => разрешенныеРасширения.Содержит(Путь.GetExtension(файл))) .К списку(); currentFoundFiles.AddRange(файлы); } поймать (UnauthorizedAccessException) { Log.Error("Поиск файлов 2: UnauthorizedAccessException"); продолжать; } улов (DirectoryNotFoundException) { Log.Error("Поиск файлов 2: UnauthorizedAccessException"); продолжать; } если (currentFoundFiles.Count public async Task RunAsync (CancellationToken cancelToken) { вар задачи = новый список(); индекс вар = 0; используя var semaphore = new SemaphoreSlim(8, 16); foreach (элементы var в FileSearcher.EnumerateFilesRecursily(@"E:/nestedAAAA", patchSize, cancelToken)) { пытаться { задачи.Добавить(Task.Run(async () => { ожидайте Task.Yield(); _logger.LogInformation($"[Задача {index}] запущена..."); foreach (элемент var в элементах) { _logger.LogInformation($"{index} нашел {item}"); } _logger.LogInformation($"[Задача {index}] выполнена..."); }, cancelToken)); индекс++; } поймать (исключение ex) { _logger.LogError(например, «Ошибка в HarvestEngine RunAsync»); семафор.Выпуск(); } } ждут Task.WhenAll(задачи); }
Мобильная версия