千家信息网

如何解决.NET Core中GetHostAddressesAsync引起的EnyimMemcached死锁问题

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章将为大家详细讲解有关如何解决.NET Core中GetHostAddressesAsync引起的EnyimMemcached死锁问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这
千家信息网最后更新 2026年11月02日如何解决.NET Core中GetHostAddressesAsync引起的EnyimMemcached死锁问题

这篇文章将为大家详细讲解有关如何解决.NET Core中GetHostAddressesAsync引起的EnyimMemcached死锁问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

在我们将站点从 ASP.NET + Windows 迁移至 ASP.NET Core + Linux 的过程中,目前遇到的最大障碍就是 -- 没有可用的支持 .NET Core 的 memcached 客户端。

我们一直用的是 EnyimMemcached ,在没有其它选择的情况下,我们自己尝试着将 EnyimMemcached 迁移至 .NET Core。。。基于 .NET Core 修改好了代码,在开发环境下测试通过,在 Linux 服务器上自己访问很正常(没有并发访问量),但是只要接入一定的访问量就会发生死锁(deadlock),浏览器请求卡死。

这个问题困扰了我们很长时间,昨天才定位到是发生在将 memcached 服务器名称解析为 IP 地址的时候。

var addresses = System.Net.Dns.GetHostAddressesAsync(host).Result;

这是我们在将 EnyimMemcached 迁移至 .NET Core 时修改过的代码,之前调用的是同步方法:

var addresses = System.Net.Dns.GetHostEntry(host);

由于在 .NET Core Framework 的 System.Net.Dns 中没有同步方法,只有异步方法,所以我们只能这样调用异步方法。

看到上面的代码,你也许会诧异:怎么用 .Result ,为什么不用 await ?不死锁才怪呢。。。

你的诧异非常正确。我们也深知 .Result 的危害,在平时的代码中坚决不用。但当时在修改 EnyimMemcached 的代码时,由于这个方法是在 MemcachedClient 的构造函数中调用的,没法改为 await 调用,被迫用了 .Result ,然后又把这个地方的修改给忘了。。。昨天才刚刚发现,立马意识到罪魁祸首非常有可能就是这里的 .Result ,于是以此为突破口,想尽一切办法实现在同步方法中调用异步办法,并且在博问中寻求支援 -- 在同步方法中调用异步方法时如何避免死锁问题 。

结果,用尽一切能想到与能找到的同步方法调用异步方法的方法,都没能解决死锁问题。如果实在找不到解决方法,我们准备采用最后一招也是最丑陋的一招 -- 不用 Dns.GetHostAddressesAsync() ,用 ProcessStartInfo 调用命令行命令解析 IP ,比如在 Linux 上用 getent hosts 主机名 。

在准备放弃之前,今天又想了想还有哪些可能带来线索的地方漏掉了呢?突然想到有个重要地方竟然忘了,还没看 Dns.GetHostAddressesAsync() 的源代码实现。虽然不报太大希望,不就是个异步方法吗,但还是要看一下。

于是从 github 上签出 corefx 的源代码,打开 Dns.GetHostAddressesAsync() 源代码一看,感觉有点怪怪的,怎么用了 Task.Factory.FromAsync() ?

public static Task GetHostAddressesAsync(string hostNameOrAddress){  NameResolutionPal.EnsureSocketsAreInitialized();  return Task.Factory.FromAsync(    (arg, requestCallback, stateObject) => BeginGetHostAddresses(arg, requestCallback, stateObject),    asyncResult => EndGetHostAddresses(asyncResult),    hostNameOrAddress,    null);}

开始没反应过来,只是把这段代码贴到博问的补充问题中,在贴完后突然反应过来了,咦,怎么没有 async 关键字?方法名最后是 Async,我们一直以为是 async 方法,而且丝毫没有怀疑过。。。

没有 async ,只是返回参数是 Task 类型,那在同步方法中调用完全没问题,只要在访问 .Result 之前调用一下 .Wait() 方法就行了,于是改为下面的代码:

Task task = System.Net.Dns.GetHostAddressesAsync(host);task.Wait();var addresses = task.Result;

死锁问题立马解决!

方法名以 Async 结尾,却不是 async 方法,当时的感想就是 -- 你的眼睛背叛你的心。如果不是我自己的误解(只要以 Async 结尾,就应该是 async 方法),那就是一种流氓行为,就如 HttpClient 的流氓 -- 实现了 IDispose 接口,却没真正 Dispose 。

不管怎么样,这个影响我们迁移至 .NET Core 的最大障碍终于消除了,值得庆祝!

支持 .NET Core 的 EnyimMemcached 的代码还需要一些修改与完善,等修改好了,我们会把源代码与 NuGet 包都发布出来。

关于"如何解决.NET Core中GetHostAddressesAsync引起的EnyimMemcached死锁问题"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

方法 问题 代码 死锁 同步 就是 源代码 地方 篇文章 最大 诧异 不用 办法 只是 命令 更多 服务器 流氓 访问量 障碍 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 有格互联网科技 圆梦互联网科技 鸠鸠互联网科技 朗新科技与工业互联网 天下捷融互联网科技 郑州华宇互联网科技 互联网科技的未来发展 深圳艾佳互联网科技 深圳期待互联网科技 成都玖崟互联网科技有限公司乐商圈怎么样 互联网科技公司需要的职位 广州优美互联网科技 中国的互联网科技企业的崛起 互联网金融中的现代科技 和信科技工业互联网 广西互联网科技孵化中心 高科技互联网发展前景如何 上海钢联属于互联网科技股吗 绵阳真晨互联网科技有限公司 杭州融税互联网科技有限公司 上海挚品互联网科技有限公司 互联网和科技技术 有马互联网科技 人人互联网科技是培训 苏州铭阳互联网科技有限公司 互联网科技圈年度人物 上海科技产业互联网平台 广东鹅鹅鹅互联网科技有限公司 美国五大互联网科技公司市值多少 互联网科技对化妆品行业
0