我正在使用一个httpclient实例发送多个请求来休息web api以获取数据。这是我的代码:
首先,我有一个控制层,用于调用数据的数据层。
public class ControlLayer
{
protected DataLayer dal;
//constructors here
public int getInfo1(int param)
{
int ret = this.dal.getInfo1(param);
return ret;
}
public int getInfo2(int param)
{
int ret = this.dal.getInfo2(param);
return ret;
}
}
然后我有调用webAPI的dataLayer,它看起来像这样。这里为了简单起见,我直接使用.result。
public class DataLayer
{
HttpClient client = new HttpClient();
string url = "";
public int getInfo1(int param1)
{
int ret=0;
HttpResponseMessage response = client.GetAsync(url).Result;
//.... do some work, get the value for ret
return ret;
}
public int getInfo2(int param1)
{
int ret = 0;
HttpResponseMessage response = client.GetAsync(url).Result;
//.... do some work, get the value for ret
return ret;
}
}
我的问题是我看到一些教程说我们应该避免使用.result,因为它可能导致死锁。在我的情况下,我不确定我是否需要使用 异步/ AWAIT?如果我确实需要,我知道我应该一直异步,但我确实希望我的controlLayer同步,因为我有其他层调用 controlLayer的功能,我不希望所有图层的功能都是异步的,结果是任务<>,这是异步同步的情况吗?我想念 什么?任何建议表示赞赏。谢谢!
答案 0 :(得分:7)
我确实想让我的controlLayer同步,因为我有其他层来调用controlLayer的函数,我不希望所有图层的函数都是异步的,结果是任务<>
我建议你重新考虑一下。 Web请求是一种基本的异步操作,因此我建议您将“控制层”公开为异步API,并允许async
通过代码库中的层“增长”。
但是,如果您真的想要一个同步API,那么您应该只调用同步API。例如,使用WebClient
代替HttpClient
。 不调用Result
以使用同步API包装异步API。
答案 1 :(得分:5)
如果您的代码是异步的,您只需要使用async
和await
- 例如,如果它同时调度多个请求,则在发送请求后执行工作,而不是仅阻塞直到响应到达。
暂时忽略死锁问题 - 如果您的代码只是同步,那就是:每次发送请求时,您只需等待响应,然后再执行其他操作,您不需要使用await
并且可以使用Result
。有关类似的辩论,请参阅this question。或者,您可以使用同步API(例如评论和其他答案中建议的WebClient
)。
对于Result
相关的死锁,我建议您阅读this article on MSDN,以便更好地了解发生的情况和原因。如果你正在编写一个简单的控制台应用程序,你真的不需要担心它(处理它的正确方法是只让你的Main方法非异步,并使用Result
或{{1那里)。