问题描述
所以我想进行很多的 DNS 查询.
So I want to make a lot of DNS queries.
我从 Begin/EndGetHostEntry
异步对创建(数千个)任务:
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
)
然后 Task.WaitAll
让一切都完成.我看到 ThreadPool
线程的数量响应我的请求而急剧增加.如果我将 ThreadPool
minThreads
强制为 500,则工作负载消耗的速度会快得多.所有这些都指向 Dns
异步实现中的阻塞.
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.
如果我将 Dns
替换为 托管 Dns 客户端,我可以只用 1或 ThreadPool
中的 2 个线程,cpu 几乎空闲.
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.
问题是,Dns
实现绝对是许多网络 API(HttpWebRequest
、WebClient
、HttpClient
>),他们似乎都受到这个问题的影响.如果我使用 3rd 方库解析 DNS,并使用 IP 地址作为 uri 中的主机发出 HTTP 请求,然后更改 Host
标头以修复请求,与任何东西相比,我的性能都非常出色涉及System.Net.Dns
.
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
.
这是怎么回事?我是否遗漏了什么,或者 System.Net.Dns
实现真的那么糟糕?
What's going on here? Have I missed something or is the System.Net.Dns
implementation really that bad?
推荐答案
System.Net.Dns 使用 windows gethostbyname
函数进行 DNS 查询,并且根本没有真正的异步函数.BeginGetHostEntry 函数基本上只是线程池上同步 GetHostEntry 调用的包装器.
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.
上次我在缓慢/同步 DNS 查找方面遇到了同样的问题,我最终只使用了一个大型 ThreadPool 来完成工作,因为没有一个内置的 Windows 或 .net DNS 相关函数支持正确的(并行)异步执行.
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.
这篇关于Dns.BeginGetHost... 方法阻塞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,WP2