Я работал над системой, которая работает с большой очередью вставок в базу данных SQL.Данные для этих вставок извлекаются из серии API, что делает общую операцию немного трудоемкой и немного тяжелой из-за сложной десериализации.Чтобы сделать весь процесс более эффективным, я предложил идею инкапсулировать обработку данных и операцию вставки для каждого вызова API в одну задачу и помещать каждую задачу в ConcurrentQueue
, одновременно отслеживая их на предмет завершения или сбоя.потом.Для этого я разработал оболочку типа Task
с присваиваемым идентификатором, который принадлежит соответствующим данным.Я реализовал этот мониторинг следующим образом:
while(processes.TryDequeue(out TaskInfo taskInfo))
{
if (!taskInfo.Task.IsCompleted) {
processes.Enqueue(taskInfo);
continue;
}
if (taskInfo.Task.IsCompletedSuccessfully)
{
Console.WriteLine("{0} Completed.", taskInfo.ReferenceId);
}
else {
Console.WriteLine("{0} Failed With {1}.", taskInfo.ReferenceId, trackableTask.Task.Exception.Message);
}
}
Как видите, я не await
выполняет задачу, а вместо этого проверяю ее статус Completed
и, если она еще не завершена, я Enqueue
задание обратно.Причина, по которой я это сделал, потому что я верил, что если я это сделаю, я могу пропустить ожидание долго выполняющейся задачи, переместив ее в конец коллекции, чтобы я мог перейти к следующей задаче и немного выполнить процесс мониторинга.Быстрее.
Я хотел бы знать, является ли то, что я сделал, плохим подходом, особенно по сравнению с методом WhenAll
, встроенным в тип задачи.Я также не уверен, правильно ли я использовал тип ConcurrentQueue
.