Как вариант, можно сделать клас, скажем, QueuedWebClientи реализовать в нем необходимые методы для загрузки данных, например тот же DownloadString. В класе сделать статический екземпляр Queueи просто добавлять в очередь ссылки по которым нужно скачать данные или делегаты, где выполняется какая-то логика загрузки. Потом если не хотите блокировать основной поток можете использовать какой-то таймер и по нему вытягивать с очереди следующий елемент. В сам клас QueuedWebClientможно добавить событие, которое будет инициироватся, когда будут готовые скачанные данные.
Но это как один из вариантов.