Нет ничего проще. :)
Я думаю, что проблемы, с которыми вы сталкиваетесь, являются неотъемлемой частью проблемной области (в отличие от простых проблем с моделью асинхронного программирования, хотя они в некоторой степени взаимодействуют).
Скажем, вы хотите загрузить 3000 фотографий. Во-первых, в вашем .NET-процессе есть что-то вроде System.Net.ConnectionLimit или что-то, имя которого я забыл, например, ограничьте число одновременных HTTP-соединений, которые ваш процесс .NET может запустить одновременно (и я думаю, что по умолчанию используется значение «2»). Таким образом, вы можете найти этот элемент управления и установить его на большее число, и это поможет.
Но затем, ваша машина и интернет-соединение имеют ограниченную пропускную способность. Таким образом, даже если вы попытаетесь одновременно запустить 3000 HTTP-соединений, каждое отдельное соединение будет работать медленнее в зависимости от ограничений канала пропускной способности. Так что это также будет взаимодействовать с таймаутами. (И это даже не учитывает, какие виды дросселей / лимитов на сервере. Может быть, если вы отправите 3000 запросов, он подумает, что вы атакуете DoS и внесет в черный список ваш IP.)
Таким образом, это действительно проблемная область, где хорошее решение требует некоторого интеллектуального регулирования и управления потоком для управления использованием основных системных ресурсов.
Как и в другом ответе, агенты F # (MailboxProcessors) являются хорошей моделью программирования для создания такой логики регулирования / регулирования потока.
(Даже при том, что, если большинство файлов изображений имеют размер 1 МБ, но в них есть файл 1 ГБ, этот единственный файл может отключиться по таймауту.)
Во всяком случае, это не столько ответ на вопрос, сколько просто указание на ту внутреннюю сложность, которая существует в самой проблемной области. (Возможно, это также наводит на мысль о том, почему «менеджеры загрузок» пользовательского интерфейса так популярны.)