Итак, я хочу сделать много запросов DNS.
Я создаю (тысячи) Заданий из пары async Begin/EndGetHostEntry:
var lookupTask = Task.Factory.FromAsync
( Dns.BeginGetHostEntry,
(Func<IAsyncResult, IPHostEntry>) Dns.EndGetHostEntry,
"google.com",
null
)
затем Task.WaitAll для завершения всего. Я вижу, что число потоков ThreadPool резко возрастает в ответ на мои запросы. Если я нажимаю ThreadPool minThreads до 500, рабочая нагрузка потребляется значительно быстрее. Все это указывает на блокировку асинхронной реализации Dns.
Если я заменил Dns на управляемый клиент Dns, я могу использовать одну и ту же рабочую нагрузку только с 1 или 2 потоками в ThreadPool с процессором практически бездействия.
Дело в том, что реализация Dns является абсолютно явной для многих сетевых API (HttpWebRequest, WebClient, HttpClient), и все они, похоже, подвержены этой проблеме. Если я разрешу DNS с помощью сторонней библиотеки и сделаю HTTP-запросы с использованием IP-адреса в качестве хоста в uri, измените заголовок Host, чтобы исправить запрос, я получаю взрывную производительность по сравнению с чем-либо, связанным с System.Net.Dns.
Что здесь происходит? Я что-то пропустил или действительно ли это реализация System.Net.Dns, что плохо?