Извиняюсь за плохой заголовок, я не уверен, как кратко описать это.
Я создаю сервис в ядре .net для обработки файлов. Общая идея заключается в том, чтобы (в цикле) проверять новые задачи, выполняемые в файле с помощью вызова БД, и, если найдено, запускать их при асинхронном выполнении. Там будет регулятор для ограничения количества запущенных задач. Если он достигнет предела, он просто подождет, пока задача будет завершена, прежде чем запустить новую. Если вызов БД ничего не возвращает, то он просто немного поспал и попробовал бы позже.
Я думаю, что это довольно просто, но я сталкиваюсь с проблемами, потому что все, что я прочитал, говорит, что вы всегда должны ждатьЗадача а не "огонь и забудь". Но если я это сделаю, то у меня останется либо синхронный запуск файлов, либо их пакетная обработка. Я что-то упускаю, я уверен.
В настоящее время это реализовано как IHostedService (особенно BackgroundService). Здесь мы используем основной метод ExecuteAsync, который выполняет эту работу. Реализован как огонь и забудь. (Visual Studio выдает предупреждение «вызов не ожидается» в Task.Run)
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var throttleTimeout = 10000;
//set up semaphore
var taskThrottler = new SemaphoreSlim(10, 10);
while (!stoppingToken.IsCancellationRequested)
{
//wait for free slot
await taskThrottler.WaitAsync(throttleTimeout,stoppingToken);
//get next file to process
var currentFile = await _fileService.GetNextFileForProcessing();
// create task
Task.Run( async
() =>
{
try
{
//do work with file tracker
var result = await _fileProcessorController.ProcessFile(currentFile);
}
finally
{
taskThrottler.Release();
}
}
, stoppingToken);
}
}
Теперь, если я изменю это и добавлю ожидание перед Task.Run, то я (по сути) работаю синхронно, потому чтокаждая задача будет ожидаться до запуска следующей ..
Если я добавлю задачи в список, я могу использовать «await Task.WhenAll (tasks);». Но потом я пакетирую.
Мне нужно уметь корректно обрабатывать неудачные задания на обработку, поэтому я думаю, что ожидание в какой-то форме является обязательным.
Все примеры, которые я нашел для решения аналогичной проблемы, обычно содержат список задач (или файлов), которые нужно выполнить заранее, а затем просто выполнить итерацию. Но я не уверен, что лучший метод, когда мне нужно добавить задачи в список при обработке других.
Возможно, что-то, что использует список задач и WhenAny? И затем я могу добавить новые задачи в список задач в каждом цикле, если таковые найдены?