Task.Run()与异步/等待

时间:2019-11-11 17:46:38

标签: c# asp.net .net asp.net-mvc

我对正在编写的某些代码有疑问。我有3个呼叫是与某些具有较大有效负载的端点同步进行的。我不想等待这些有效负载,而是继续运行该方法,直到需要来自这三个端点的值为止。

我已经找到了这样的解决方案。我将调用3个服务端点的方法转换为异步方法。我使用

调用数据

var serviceCallOneTask = Task.Run(()=> serviceCallOne());

注意serviceCallOne()不是异步的 最后,当我需要数据时,我会执行

var serviceCallOneValue = await serviceCallOneTask;

我的问题是

  1. 此解决方案是否被视为不好的做法?
  2. 我应该担心僵局吗?
  3. 据我所读,当使用await时,我们不是在阻塞线程,而在使用task.run时,我们是在使用CPU绑定线程,并且在阻塞线程池。那是对的吗?
  4. 对我来说,将此httpGet方法中的所有内容从头到尾转换为异步方法是否更好?
  5. 现在可以以后将那些task.run()服务转换为异步方法了吗?

1 个答案:

答案 0 :(得分:1)

  
      
  1. 此解决方案是否被视为不良做法?
  2.   

这取决于您在做什么。

Task.Run将执行移至另一个线程。这对桌面应用程序很有用,因为您不希望长时间运行的CPU绑定操作在UI线程上运行并锁定UI。

ASP.NET有所不同,因为没有UI线程,因此除非您要并行执行某些操作(同时运行两个受CPU限制的操作),否则无需将操作移至另一个线程。

如果您在调用Task.Runawait serviceCallOneTask之间正在做其他事情,那么那当然就是做您正在做的事情的原因。但是,是否“更好”取决于serviceCallOne()在做什么。您必须考虑两件事,以确定收益是否超过成本:

  1. 在单独的线程中运行的好处是否超过了将其移至单独的线程的成本? (实际上, 要比在同一线程中运行它快吗?)
  2. 请记住,ASP.NET具有有限数量的线程(默认情况下,每个处理器20个),现在您使用的是2个线程而不是1个线程。根据您的应用程序的预期负载,这可能或可能不重要。
  
      
  1. 我应该担心死锁吗?
  2.   

没有显示的一小段代码。只要您don't wait synchronously on an async method,您就不必担心死锁。

  
      
  1. 据我所读,当使用await时,我们不是在阻塞线程,而在使用task.run时,我们是在使用CPU绑定线程,并且在阻塞线程池。正确吗?
  2.   

使用await时,您不会阻塞 current 线程。如上所述,根据您的代码,您可能只是阻塞了另一个线程。

  
      
  1. 对我来说,将此httpGet方法中的所有内容从头到尾转换为异步方法是否更好?
  2.   

考虑ASP.NET具有的有限线程,并且async / await可以帮助您释放线程,然后可以。尽可能使用async总是更好。

  
      
  1. 现在可以以后将那些task.run()服务转换为异步方法了吗?
  2.   

如果可以,那就没问题。但是您必须更改某些内容,对吗?也可以做对。 :)