这是在将 memcached 客户端 EnyimMemcached 迁移至 .Net Core 遇到的问题。
在 MemcachedClient 的构造函数中创建 socket 连接池时,有一个将主机名解析为 IP 地址的操作,之前调用的是同步的 System.Net.Dns.GetHostEntry() 方法,但在 .NET Core 中只有异步的 System.Net.Dns.GetHostAddressesAsync() 方法,所以被迫改为这样调用:
var addresses = System.Net.Dns.GetHostAddressesAsync(host).Result;
结果只要使用 EnyimMemcached 的 ASP.NET Core 站点在 Linux 上一运行,多个请求进来,就发生死锁(deadlock)。从浏览器端看,请求发出后,就一直处于等待状态。
不管改为:
var addresses = GetHostAddressesAsync(host).ConfigureAwait(false).GetAwaiter().GetResult();
还是改为:
var addresses = await Task.Run(async () => { return await System.Net.Dns.GetHostAddressesAsync(host); });
都会发生死锁。
你也许会说,干脆将上层调用方法都改成异步的,但是最上层是 MemcachedClient 的构造函数,没法改为异步的。如果真要将创建 socket 连接池的操作改为异步的,需要对 EnyimMemcached 的代码进行大动作。
目前还是打算直接在同步方法中调用异步方法,所以请教一下大家看有没有什么法子避开死锁?