Ответ 1
Причина - это ограничение количества HTTP-соединений, которое игнорируется при использовании Fiddler.
Я столкнулся с таким же поведением при использовании System.Net.Http.HttpClient
для выполнения нескольких (~ 80) одновременных запросов. С запуском Fiddler все запросы выполнялись намного быстрее. Keep-alive, безусловно, был включен.
Я использовал Wireshark, чтобы узнать, что происходит, и, во-первых, я заметил, что способ http-трафика отличается. С запросами Fiddler были брошены все сразу, и после этого ответы также были хорошо сгруппированы. Без Fiddler запросы чередуются с ответами.
Во-вторых, tcpview показал, что мой код без Fiddler создал только 2 tcp-соединения с сервером. С запуском Fiddler количество соединений резко увеличилось. Их было десятки от моего приложения до Fiddler, а затем от Fiddler до сервера.
Хорошо известно, что стандарт http рекомендует, чтобы количество HTTP-соединений не превышало 2, и кажется, что предел реализован как параметр по умолчанию в http-клиентах.
В приложениях .NET мы можем контролировать предел с помощью статического свойства ServicePointManager.DefaultConnectionLimit
. В качестве эксперимента, установив его на 100, запросы выполнялись с той же скоростью с или без Fiddler.
Настройка также можно контролировать с помощью app.config:
<system.net>
<connectionManagement>
<add address="*" maxconnection="100" />
</connectionManagement>
</system.net>
Теперь, почему ограничение по умолчанию, которое не соблюдается при использовании Fiddler? Оказывается, предел отличается, когда клиент-клиент использует прокси-сервер, а Fiddler действует как прокси-сервер. Я не нашел много информации о пределе прокси-соединения, кроме этой старой статьи.