Reputation: 13875
I am making HTTP calls using the System.Net.Http.HttpClient
. It seems that all calls must be asynchronous.
Let's say I have a project structure of the following: MVC Web App -> Business Layer -> Data Layer
In the Data Layer I am making HTTP calls to a Web API to return data and I end up using a function like this:
public async Task<IList<Product>> GetProducts()
{
HttpResponseMessage response = await client.GetAsync("api/products");
string data = await response.Content.ReadAsStringAsync();
IList<Product> products = JsonConvert.DeserializeObject<IList<Product>>(data);
return products;
}
this then goes through to the BusinessLayer:
public Task<IList<Product>> GetProducts(string name = null)
{
return _repository.GetProducts(name);
}
Then finally in the MVC controller:
public IActionResult Index()
{
Task<IList<Product>> ProductsTask = _manager.GetProducts();
IList<Product> ProductsNonTask = products.Result.ToList();
return View();
}
Do I really have to make every single function return a list of type Task<IList<Product>>
leading up to my MVC controller? As you can see in the MVC controller I have to retrieve the products initially with Task wrapped around them. The debugger looks kind of strange when I go to view the list of products through it. So then as you can see I convert them to a regular list of product.
I am wondering if it is the correct thing to do to have all of my functions return type Task<IList<Product>>
all the way up to my MVC controller or if there is a workaround so that my functions can still return the a standard list of product but continue to use the async capabilities of the HttpClient
?
UPDATE: Is there anything wrong with doing the following:
public IList<Product> GetProducts()
{
Task<HttpResponseMessage> response = client.GetAsync("api/products");
if (response.Result.IsSuccessStatusCode)
{
string data = response.Result.Content.ReadAsStringAsync().Result;
IList<Product> products = JsonConvert.DeserializeObject<IList<Product>>(data);
retVal = products;
}
}
Upvotes: 5
Views: 1690
Reputation: 116596
If you want the operation to actually be asynchronous it needs to be asynchronous all the way up.
The minute you block on a Task
with Wait
or Result
it's no longer asynchronous.
So, no. Either use async all the way up or be don't use it at all.
I wonder... if there is a workaround so that my functions can still return the a standard list of product but continue to use the async capabilities of the HttpClient?
No, there isn't really.
You should probably just make your code asynchronous as it comes with many benefits in scalability and performance. But if you're against doing so you can use WebClient
that has synchronous web operations.
Upvotes: 7
Reputation: 171206
Do I really have to make every single function return a list of type Task> leading up to my MVC controller?
Yes, you have to and you didn't even catch all places because Index
itself must be async, too.
Async is really infectious. Use when necessary, not by default.
Upvotes: 1