异步等待调用长时间运行同步和异步方法

时间:2016-07-24 20:11:21

标签: c# asp.net asynchronous async-await asp.net-web-api2

我正在使用asp.net web api 2和Entity Framework 6。

原始伪代码

public IHttpActionResult GetProductLabel(int productId)
{
      var productDetails = repository.GetProductDetails(productId); 
      var label = labelCalculator.Render(productDetails);  
      return Ok(label);
}

修改后的代码

public async Task<IHttpActionResult> GetProductLabel(int productId)
{
      var productDetails = await repository.GetProductDetailsAsync(productId); // 1 long second as this call goes into sub services
      var label = labelCalculator.Render(productDetails); // 1.5 seconds synchrounous code
      return Ok(label);
}

在我改变之前,一切都是同步进行的。

在我改变后,再次调用数据库的远程服务的调用是以async-await方式完成的。

然后我对一个只提供同步方法的渲染库进行同步调用。计算需要1.5秒。

我是否仍然有一个好处,我做远程database_service调用async-await方式,但第二次调用不?还有什么我还能改进的吗?

注意

我之所以这样问是因为:

&#34;当进程等待I / O完成时,使用异步控制器,释放其线程以供服务器用于处理其他请求。&#34;

因此,当第一个远程database_service调用正在处理并等待1秒钟时,该线程将返回给IIS ?? !!

但是第二个标签计算需要1.5秒才能再次阻止当前线程1.5秒?

所以我发布并阻止线程,这没有意义或者您认为怎么样?

3 个答案:

答案 0 :(得分:2)

渲染库不仅仅是“阻塞线程”,它正在执行渲染工作。你无能为力。

答案 1 :(得分:1)

异步代码在底层创建了一个特定的延续,它是一种合成糖,使异步编程感觉更加同步。

通常,根据操作本身,它可以帮助使两个长时间运行的任务异步。对于每个不同的长时间运行任务,它将使用不同的任务并以异步方式运行它们。

目前,这些任务在GetProductLabel中完全同步运行,这意味着如果它是您调用的唯一方法,则无法区分同步代码。

如果可能,我会将第二种方法设为异步,因为我不熟悉使用任务和异步等待的任何明显缺点。

在你的情况下,你没有什么比这更好的了,因为你必须同步运行它,因为你正在使用第一种方法的结果。

答案 2 :(得分:1)

  

我做远程database_service调用还有什么好处   async-await方式,但第二次呼叫不是?

是的,此调用现在是非阻塞的,并且可以与其他代码一起运行,即使它只持续1秒。

  

还有什么我还能改进吗?

如果您也可以异步运行第二个调用,则整个方法可以异步运行并且根本不会阻塞。