使用HttpClient时,避免从异步函数返回类型Task <object>

时间:2016-01-27 21:04:18

标签: c# asp.net-mvc asp.net-web-api async-await httpclient

我正在使用System.Net.Http.HttpClient进行HTTP调用。似乎所有调用都必须是异步的。

假设我有以下项目结构: MVC Web App - &gt;业务层 - &gt;数据层

在数据层中,我正在对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;
}

然后进入BusinessLayer:

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

然后终于在MVC控制器中:

public IActionResult Index()
{
    Task<IList<Product>> ProductsTask = _manager.GetProducts();

    IList<Product> ProductsNonTask = products.Result.ToList();

    return View();
}

我是否真的必须让每个函数都返回一个类型为Task<IList<Product>>的列表,直到我的MVC控制器?正如你在MVC控制器中看到的那样,我必须首先检索产品,并将Task包裹起来。当我通过它查看产品列表时,调试器看起来很奇怪。那么你可以看到我将它们转换为常规产品列表。

我想知道让我的所有函数返回类型Task<IList<Product>>一直到我的MVC控制器是否是正确的做法,或者如果有一个解决方法以便我的函数仍然可以返回a标准产品列表,但继续使用HttpClient

的异步功能

更新:执行以下操作有什么问题:

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;
     }
}

2 个答案:

答案 0 :(得分:7)

如果您希望操作实际上是异步的,则需要一直异步。

您使用TaskWait Result屏蔽的时间不再异步。

所以,不。要么一直使用异步,要么根本不使用它。

  

我想知道......如果有一个解决方法,以便我的函数仍然可以返回标准的产品列表,但继续使用HttpClient的异步功能?

不,真的没有。

您应该只是使代码异步,因为它在可伸缩性和性能方面具有许多优势。但是,如果您不这样做,可以使用具有同步网络操作的WebClient

答案 1 :(得分:1)

  

我是否真的必须让每个函数都返回一个类型为Task&gt;的列表。导致我的MVC控制器?

是的,你必须和你甚至没有抓到所有地方,因为Index本身也必须是异步的。

异步真的很有感染力。必要时使用,而不是默认使用。