C#ASP.NET核心API异步/等待VS结果
我对c#和任务的最佳实践有点困惑。C#ASP.NET核心API异步/等待VS结果,c#,asp.net-core,async-await,asp.net-core-webapi,C#,Asp.net Core,Async Await,Asp.net Core Webapi,我对c#和任务的最佳实践有点困惑。 当我学习c#和任务时,它总是一个等待任务的异步函数。但最近我做了一些研究,发现有些人不这么认为。他们还说,限制async和await的使用可以提高性能和Ram的使用 例如,它说你不应该总是等待每一个任务,但是这个例子并不适用于ASP.NET API,也没有任何以前的数据用于获取新数据。 也赞成不要总是等待每一项任务。但是,这个例子同样是一个简单的任务 因此,我的问题是,当有另一个任务必须等待第二个任务时。您可以使用.Result还是使用async/await更
当我学习c#和任务时,它总是一个等待任务的异步函数。但最近我做了一些研究,发现有些人不这么认为。他们还说,限制async和await的使用可以提高性能和Ram的使用 例如,它说你不应该总是等待每一个任务,但是这个例子并不适用于ASP.NET API,也没有任何以前的数据用于获取新数据。 也赞成不要总是等待每一项任务。但是,这个例子同样是一个简单的任务 因此,我的问题是,当有另一个任务必须等待第二个任务时。您可以使用
.Result
还是使用async/await更好。因为我听说。Result
正在阻止当前线程。
但是我看不出当前线程如何不被wait阻塞,因为第一条语句的输出对于第二条语句是必需的
没有异步/等待的示例
public Task<User> SaveUser(User user)
{
var dbUser = _userRepository.GetByUid(user.Id).Result;
if(dbUser == null) {
dbUser = new User();
dbUser.Id = Guid.NewGuid();
}
dbUser.Name = user.Name;
return _userRepository.Save(dbUser);
}
public async Task<User> SaveUser(User user)
{
var dbUser = await _userRepository.GetByUid(user.Id);
if(dbUser == null) {
dbUser = new User();
dbUser.Id = Guid.NewGuid();
}
dbUser.Name = user.Name;
return await _userRepository.Save(dbUser);
}
公共任务保存用户(用户)
{
var dbUser=\u userRepository.GetByUid(user.Id).Result;
if(dbUser==null){
dbUser=新用户();
dbUser.Id=Guid.NewGuid();
}
dbUser.Name=user.Name;
返回_userRepository.Save(dbUser);
}
使用async/await的示例
public Task<User> SaveUser(User user)
{
var dbUser = _userRepository.GetByUid(user.Id).Result;
if(dbUser == null) {
dbUser = new User();
dbUser.Id = Guid.NewGuid();
}
dbUser.Name = user.Name;
return _userRepository.Save(dbUser);
}
public async Task<User> SaveUser(User user)
{
var dbUser = await _userRepository.GetByUid(user.Id);
if(dbUser == null) {
dbUser = new User();
dbUser.Id = Guid.NewGuid();
}
dbUser.Name = user.Name;
return await _userRepository.Save(dbUser);
}
公共异步任务SaveUser(用户)
{
var dbUser=await\u userRepository.GetByUid(user.Id);
if(dbUser==null){
dbUser=新用户();
dbUser.Id=Guid.NewGuid();
}
dbUser.Name=user.Name;
返回wait_userRepository.Save(dbUser);
}
注意:我还听说在使用UI时,等待与UI相关的任务是很重要的,但这将是API的任务。我建议阅读我的文章,并在上继续我的文章。TL;DR:默认情况下使用async
/await
,并且仅当方法是简单的passthrough方法时才删除它们。由于您的示例不是一个简单的passthrough方法,因此您应该保持async
/wait
关键字
区分“异步”和async
也很重要。异步代码有几种,而async
是一种实现细节——一种特定的异步代码。问题中的两个方法都是异步的,但只有一个使用async
他们还说,限制async和await的使用可以提高性能和Ram的使用
是的,通过删除async
关键字的状态机开销。但是,这也消除了状态机的所有优点,因此您应该只在简单的passthrough方法上删除async
您可以使用.Result还是使用async/await更好。因为我听说了。结果是阻塞了当前线程
您应该尽可能使用async
/wait
,甚至
但是我看不出当前线程如何不被wait阻塞,因为第一条语句的输出对于第二条语句是必需的
线程没有阻塞
wait
的工作原理是在方法中粘贴书签,然后返回结果。因此线程没有被阻塞,但您可以将该方法视为“暂停” 你误解了你读到的东西。这篇文章没有说你应该使用.Result
。如果只返回任务而不在方法中使用其结果,则不需要等待。这里的情况并非如此,因此您应该始终使用wait
,但这个示例同样是一个简单的任务。这是唯一可以省略wait
的情况<代码>异步/等待
不要使方法异步async
只是一种语法糖,它允许使用await
等待一个已经异步的方法完成而不被阻塞。这将是针对API的。
在这里更为重要-与其阻止单个用户,还不如冻结整个服务器,或者延迟站点上的每个请求。每个请求都由来自线程池的单独线程提供服务。在避免阻塞的情况下,相同数量的线程(和内核)可以用于在同一个铁上处理更多的请求