Вы можете использовать Task.WhenAll
для массива задач: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netframework-4.8
Создает задачу, которая завершится после завершения всех поставленных задач.
Вот пример того, что я имею в виду:
var tasks = new List<Task>();
using (WebClient client = new WebClient())
{
foreach (string url in urlList)
{
tasks.Add(client.DownloadData(url)));
}
await Task.WhenAll(tasks);
}
Это, по сути, запустит все запросов, затем ждет их выполнения, прежде чем продолжить, значит что вы делаете не один запрос, ожидание, второй запрос, ожидание и т. д. c ....
Несколько замечаний по поводу вашего кода:
Вам следует не возвращать void при выполнении асинхронного кода
Вот некоторая информация: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/async-return-types#BKMK_VoidReturnType
Вы используете тип возврата void в обработчиках асинхронных событий, которые требуется тип возврата void. Для методов, отличных от обработчиков событий, которые не возвращают значение, вы должны вместо этого вернуть Task, потому что нельзя ожидать asyn c метода, который возвращает void. Любой вызывающий такой метод должен иметь возможность продолжить выполнение, не дожидаясь, пока вызываемый метод asyn c завершится до sh, и вызывающий должен быть независим от любых значений или исключений, которые генерирует метод asyn c.
HttpClient - это новый API
WebClient
Я думаю, это старый способ ведения дел? C# быстро движется в эти дни: { ссылка } у него аналогичная производительность, и вы можете использовать его очень похожим образом
Вы, вероятно, должны проверять код состояния, а не перехватывать исключения
Я мог бы написать эссе о разрешении исключений для создания потока управления, но пока давайте будем простыми, коды состояния http могут определять, успешны они или нет - используйте их.
Надеюсь, это поможет