我在youtube上看过Les Jackson关于如何创建.net核心api的一些视频。Les在他的控制器中使用了这种方法
public ActionResult<IEnumerable<Command>> GetAllCommands()
{
var commandItems = _repository.GetAppCommands();
return Ok(commandItems);
}
然而,我刚刚读到一本书中的一篇文章,其中使用了这种方法
public async Task<ActionResult<IEnumerable<Data.CityDataClass>>> GetCities()
{
return await _repository.GetCities();
}
在我看来,第二种方法是过度使用";异步;公告第一个方法在得到结果之前不会返回任何内容。
感谢
如果阅读这篇关于I/O线程的文章,您可以更好地理解这一点
使用的异步和并行功能。NET,您还应该理解I/O线程的概念。
并非程序中的所有内容都会消耗CPU时间。当线程试图从磁盘上的文件读取数据或通过网络发送TCP/IP数据包时,它所做的唯一事情就是将实际工作委托给设备(磁盘或网络适配器(并等待结果。
I/O线程是一种抽象,旨在将设备工作隐藏在一个简单而熟悉的概念后面。这里的要点是,你不必以不同的方式处理这些设备,你可以把它们内部的管道想象成一个通常消耗CPU的线程。同时,与CPU绑定线程相比,I/O线程非常便宜,因为事实上,它们只是对设备的请求
因此,使用第一种方法,您不是在使用I/O线程,而是使用第二种方法,而且它要便宜得多。
在您的情况下,访问数据库时,实际上是在执行I/O(网络(操作。通过使用异步编程,您在I/O线程上等待I/O(db-read(操作完成,而不会阻塞线程。
编辑(Liam评论后(
另一个有趣的阅读是深度异步
在整个过程中,一个关键的收获是没有线程专门用于运行任务。尽管工作是在某些上下文中执行的(也就是说,操作系统必须将数据传递给设备驱动程序并对中断做出响应(,但没有专门用于等待请求中的数据返回的线程。这允许系统处理更大的工作量,而不是等待某个I/O调用完成。
有关更多信息,请查看此处的异步开销
- 如果异步方法同步完成,则性能开销相当小
- 如果异步方法同步完成,将出现以下内存开销:对于异步任务方法,没有开销,对于异步任务方式,每个操作的开销为88字节(在x64平台上(
- ValueTask可以消除上面提到的同步完成的异步方法的开销
- 如果方法同步完成,则基于ValueTask的异步方法比基于Task的方法快一点,否则则慢一点
- 等待未完成任务的异步方法的性能开销要大得多(x64平台上的每个操作约300字节(