Search code examples
c#asynchronousdnsblocking

Dns.BeginGetHost... methods blocking


So I want to make a lot of DNS queries.

I create (thousands) of Tasks from the Begin/EndGetHostEntry async pair:

var lookupTask = Task.Factory.FromAsync
   ( Dns.BeginGetHostEntry,
     (Func<IAsyncResult, IPHostEntry>) Dns.EndGetHostEntry,
     "google.com", 
     null
   )

then Task.WaitAll for everything to complete. I'm seeing the number of ThreadPool threads increase drastically in response to my requests. If I force the ThreadPool minThreads to 500, the workload is consumed considerably faster. All of this points to blocking in the Dns asynchronous implementation.

If I replace Dns with a managed Dns client, I can consume the same workload with only 1 or 2 threads in the ThreadPool with cpu virtually idling.

The thing is, the Dns implementation is absolutely core to many networking APIs (HttpWebRequest, WebClient, HttpClient), and they all seem to be affected by this issue. If I resolve DNS with a 3rd party library, and make HTTP requests using the IP address as the host in the uri, then alter the Host header to fix the request, I get blistering performance in comparison to anything involving System.Net.Dns.

What's going on here? Have I missed something or is the System.Net.Dns implementation really that bad?


Solution

  • System.Net.Dns uses the windows gethostbyname function for DNS queries and doesn't really have asynchronous functions at all. The BeginGetHostEntry function is basically just a wrapper for a synchronous GetHostEntry invocation on the thread pool.

    Last time I had this same problem with slow/synchronous DNS lookups I eventually just used a large ThreadPool to get the job done since not a single built-in windows or .net DNS related function supports proper (parallel) asynchronous execution.