Reputation: 23
I'm using one httpclient instance to send multiple requests to rest web api to get data. Here is what my code looks like:
First I have a control layer that calls the data layer for data.
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;
}
}
then I have the dataLayer that calls webAPI, it looks like this. here for simplicity, im using .result directly.
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;
}
}
my questions is I've seen some tutorials saying that we should avoid using .result, because it might lead to deadlock. I'm not sure in my case do I need to use async/await? if I do need, I know I should async all the way down, but I do want my controlLayer to be sync, because I have other layer that calls the controlLayer's function, I don't want all the layer's function to be async and the result be Task<>, is this a situation of sync over async? am I miss something? any suggestions are appreciated. thanks!
Upvotes: 2
Views: 12791
Reputation: 16563
You only need to use async
and await
if your code is asynchronous - for example if it dispatches several requests simultaneously, doing work after a request is sent instead of just blocking until the response arrives.
Ignoring the deadlock issue for a moment - if your code is simply synchronous, that is: every time you send a request you just wait for the response before doing anything else, you don't need to use await
and can use Result
. See this question for a similar debate. Alternatively, you can use a synchronous API (such as WebClient
as suggested in the comments and other answer).
As for Result
-related deadlocks, I recommend you read this article on MSDN for a better understanding of what happens and why. If you're writing a simple console application, you don't really need to worry about it (the right way to deal with it is to have only your Main method non-async, and use Result
or Wait
there).
Upvotes: 5
Reputation: 457217
I do want my controlLayer to be sync, because I have other layer that calls the controlLayer's function, I don't want all the layer's function to be async and the result be Task<>
I recommend you rethink this. A web request is a fundamentally asynchronous operation, so I recommend that you expose your "control layer" as an asynchronous API and allow the async
to "grow" through the layers in your code base.
However, if you really want a synchronous API, then you should only call synchronous APIs. E.g., use WebClient
instead of HttpClient
. Do not call Result
to wrap an asynchronous API with a synchronous API.
Upvotes: 7