简体   繁体   English

避免返回类型任务 <Object> 使用HttpClient时从异步函数

[英]Avoid returning type Task<Object> from an async function when using HttpClient

I am making HTTP calls using the System.Net.Http.HttpClient . 我正在使用System.Net.Http.HttpClient进行HTTP调用。 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 假设我有以下项目结构: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: 在数据层中,我正在对Web API进行HTTP调用以返回数据,我最终使用如下函数:

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: 然后进入BusinessLayer:

public Task<IList<Product>> GetProducts(string name = null)
{
     return _repository.GetProducts(name);
}

Then finally in the MVC controller: 最后在MVC控制器中:

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? 我是否真的必须让每个函数都返回一个类型为Task<IList<Product>>的列表,直到我的MVC控制器? As you can see in the MVC controller I have to retrieve the products initially with Task wrapped around them. 正如你在MVC控制器中看到的那样,我必须首先检索产品,并将Task包裹起来。 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 ? 我想知道是否正确的做法是让我的所有函数返回类型Task<IList<Product>>一直到我的MVC控制器或者如果有一个解决方法使我的函数仍然可以返回一个标准产品列表但继续使用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;
     }
}

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. 您在具有WaitResultTask上阻止的那一刻它不再是异步的。

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? 我想知道...如果有一个解决方法,以便我的函数仍然可以返回标准的产品列表,但继续使用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. 但是,如果您反对这样做,您可以使用具有同步Web操作的WebClient

Do I really have to make every single function return a list of type Task> leading up to my MVC controller? 我是否真的必须让每个函数返回一个类型为Task>的列表导致我的MVC控制器?

Yes, you have to and you didn't even catch all places because Index itself must be async, too. 是的,你必须和你甚至没有赶上所有地方,因为Index本身也必须是异步的。

Async is really infectious. 异步真的很有感染力。 Use when necessary, not by default. 必要时使用,而不是默认使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM