在同步方法中调用异步方法时如何避免死锁问题
2016-09-21 17:14
351 查看
这是在将 memcached 客户端 EnyimMemcached 迁移至 .Net Core 遇到的问题。
在 MemcachedClient 的构造函数中创建 socket 连接池时,有一个将主机名解析为 IP 地址的操作,之前调用的是同步的 System.Net.Dns.GetHostEntry() 方法,但在 .NET Core 中只有异步的 System.Net.Dns.GetHostAddressesAsync() 方法,所以被迫改为这样调用:
结果只要使用 EnyimMemcached 的 ASP.NET Core 站点在 Linux 上一运行,多个请求进来,就发生死锁(deadlock)。从浏览器端看,请求发出后,就一直处于等待状态。
不管改为:
还是改为:
都会发生死锁。
你也许会说,干脆将上层调用方法都改成异步的,但是最上层是 MemcachedClient 的构造函数,没法改为异步的。如果真要将创建 socket 连接池的操作改为异步的,需要对 EnyimMemcached 的代码进行大动作。
目前还是打算直接在同步方法中调用异步方法,所以请教一下大家看有没有什么法子避开死锁?
在 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 的代码进行大动作。
目前还是打算直接在同步方法中调用异步方法,所以请教一下大家看有没有什么法子避开死锁?
相关文章推荐
- 又踩.NET Core的坑:在同步方法中调用异步方法Wait时发生死锁(deadlock)
- WCF方法“异步调用”的“同步问题”
- 一码阻塞,万码等待:APS.NET Core 同步方法调用异步方法“死锁”的真相
- async await 同步方法调用异步方法死锁
- 又踩.NET Core的坑:在同步方法中调用异步方法Wait时发生死锁(deadlock)
- WCF热门问题编程示例(4):WCF客户端如何异步调用WCF服务?
- javascript异步调用的同步问题
- JQuery ajax 如何设置同步调用(同时只能触发一个函数) 解决与层显示信息时候的冲突问题
- WCF热门问题编程示例(4):WCF客户端如何异步调用WCF服务?
- 如何异步调用方法
- 使用异步方式调用同步方法
- 【转载】WCF热门问题编程示例(4):WCF客户端如何异步调用WCF服务?
- 如何异步调用 visual c# 方法
- Silverlight中通过Javascript的XmlHttp调用服务器端内容的同步与异步问题
- Flex4 数据库异步调用问题及解决方法
- Struts 2中如何用一个action调用多个方法,避免每一个方法写一个action的繁琐之处
- Java 如何把异步调用模拟成同步调用
- 今天遇到了"从不同步的代码块中调用了对象同步方法"问题
- C# 异步编程 异步委托调用同步方法
- C#的新特性体验(异步方法的同步调用)