从 Web API 同步调用外部 api
Posted
技术标签:
【中文标题】从 Web API 同步调用外部 api【英文标题】:Call external api from Web API synchronously 【发布时间】:2015-02-16 22:30:08 【问题描述】:我需要从我的 Web API 2 控制器调用外部 api,类似于这里的要求:
Calling external HTTP service using HttpClient from a Web API Action
但是,上面的解决方案需要在我的 api 方法的 GET 调用中添加 async
关键字,从而使我的调用异步。我更喜欢使用同步方法向我的 API 的客户端呈现,但仍然能够从我自己的调用外部 api(并且需要在我的 api 返回之前返回)。有没有办法做到这一点?
【问题讨论】:
【参考方案1】:阻止async
操作可能很危险。它会损害性能并可能导致死锁(更多内容请参见 Should I expose synchronous wrappers for asynchronous methods?)
但是,如果您确定这是您想要做的,IMO 最好使用GetAwaiter().GetResult()
:
using (HttpClient httpClient = new HttpClient())
var response = httpClient.GetAsync(_endpoint).GetAwaiter().GetResult();
var result = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
// Do stuff...
无论是Task
还是Task<T>
,都是一样的,await
转换为相同的调用(尽管await
任务已经完成)并且Task.Result
(或Task.Wait
)包含任何异常在AggregateException
中,而GetAwaiter().GetResult()
只抛出第一个Exception
,就像await
一样。
【讨论】:
感谢您的提醒...经过进一步研究后,我确定最好让客户端决定是否异步调用 api。我还发现这篇文章更简洁地解释了这个问题:blog.stephencleary.com/2012/07/dont-block-on-async-code.html以上是关于从 Web API 同步调用外部 api的主要内容,如果未能解决你的问题,请参考以下文章
使用 Celery 通过 Gevent 进行实时、同步的外部 API 查询