C# aspnet标识中的异步代码有误导性
我需要为AsNetIdentity实现自定义存储提供程序。 我仔细看了一下四周,发现了不少,但我觉得它们都错了C# aspnet标识中的异步代码有误导性,c#,async-await,c#-5.0,C#,Async Await,C# 5.0,我需要为AsNetIdentity实现自定义存储提供程序。 我仔细看了一下四周,发现了不少,但我觉得它们都错了 我的理解是,如果您有一个以“async”结尾的方法,那么它应该以asynchronous结尾 请看从某人的代码中选取的示例,这些示例分散在各个地方 我发现以下内容非常误导,因为从我所看到的内容来看,它根本不是异步的: public Task<TUser> FindByIdAsync(int userId) { TUser result = u
我的理解是,如果您有一个以“async”结尾的方法,那么它应该以asynchronous结尾 请看从某人的代码中选取的示例,这些示例分散在各个地方 我发现以下内容非常误导,因为从我所看到的内容来看,它根本不是异步的:
public Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserById(userId) as TUser; //this is not async
if (result != null)
{
return Task.FromResult<TUser>(result);
}
return Task.FromResult<TUser>(null);
}
公共任务FindByIdAsync(int userId)
{
TUser result=userTable.GetUserById(userId)as TUser;//这不是异步的
如果(结果!=null)
{
返回Task.FromResult(结果);
}
返回Task.FromResult(空);
}
应该这样编码吗?:
public async Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return await Task.FromResult<TUser>(result);
}
return await Task.FromResult<TUser>(null);
}
Questions?
公共异步任务FindByIdAsync(int userId)
{
TUser result=userTable.GetUserByIdAsync(userId)作为TUser;
如果(结果!=null)
{
返回等待任务。FromResult(result);
}
返回等待任务.FromResult(空);
}
问题?
非常感谢您的反馈初始代码绝对不是异步的。它看起来是为了应付API设计而采用的 然而,在我看来,提议的更改也不是异步的。
Task.FromResult
只是创建一个带有结果的已完成任务,不会使任何内容异步或执行任何类型的等待代码,因此您不应该等待它
在您的情况下,假设GetUserByIdAsync
返回一个任务,并且假设此代码(看起来)的全部目的是始终返回一个已完成的任务(从未出错或取消),则可以将其重写为:
public async Task<TUser> FindByIdAsync(int userId)
{
var tResult = userTable.GetUserByIdAsync(userId);
TUser result = null;
try
{
result = await tResult;
}
except
{
// Bad idea, but here goes to your first snippet
}
return Task.FromResult<TUser>(result);
}
最初的代码绝对不是异步的,它看起来像是用来处理API设计的
然而,在我看来,提议的更改也不是异步的。Task.FromResult
只是创建一个带有结果的已完成任务,不会使任何内容异步或执行任何类型的等待代码,因此您不应该等待它
在您的情况下,假设GetUserByIdAsync
返回一个任务,并且假设此代码(看起来)的全部目的是始终返回一个已完成的任务(从未出错或取消),则可以将其重写为:
public async Task<TUser> FindByIdAsync(int userId)
{
var tResult = userTable.GetUserByIdAsync(userId);
TUser result = null;
try
{
result = await tResult;
}
except
{
// Bad idea, but here goes to your first snippet
}
return Task.FromResult<TUser>(result);
}
async
方法是编译器构建某种东西的一种方法,它将返回一个承诺我们的未来
await
指令接受任何awaitable,而Task
恰好是其中之一。它不知道或不关心所调用的方法/操作是否真正异步
Task.FromResult
返回已完成的任务,如果在async
方法中的wait
指令中使用该任务,则将认为该任务已同步完成,并将继续执行
因此,使用async
和wait
只需调用Task.FromResult
编译器生成的代码将在运行时浪费更多的CPU周期和内存,从而浪费CPU周期和内存
因为async
方法总是返回任务
,所以决定将其隐式化以提高可读性,并给它某种sync的感觉。编译将把返回值包装在任务
中。这就是为什么不能返回任务.FromResult(result)
或任务.FromResult(null)
直接输入,并等待它获取值
因此,同步代码的async
等价物是:
public async Task<TUser> FindByIdAsync(int userId)
{
var result = await userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return result;
}
return null;
}
公共异步任务FindByIdAsync(int userId)
{
var result=await userTable.GetUserByIdAsync(userId)作为TUser;
如果(结果!=null)
{
返回结果;
}
返回null;
}
或:
公共异步任务FindByIdAsync(int userId)
{
返回wait-userTable.GetUserByIdAsync(userId)作为TUser;
}
异步方法是编译器构建某种东西的一种方法,它将返回一个承诺我们的未来。对于.NET Framework和C#,这是一个任务
await
指令接受任何awaitable,而Task
恰好是其中之一。它不知道或不关心所调用的方法/操作是否真正异步
Task.FromResult
返回已完成的任务,如果在async
方法中的wait
指令中使用该任务,则将认为该任务已同步完成,并将继续执行
因此,使用async
和wait
只需调用Task.FromResult
编译器生成的代码将在运行时浪费更多的CPU周期和内存,从而浪费CPU周期和内存
因为async
方法总是返回任务
,所以决定将其隐式化以提高可读性,并给它某种sync的感觉。编译将把返回值包装在任务
中。这就是为什么不能返回任务.FromResult(result)
或任务.FromResult(null)
直接输入,并等待它获取值
因此,同步代码的async
等价物是:
public async Task<TUser> FindByIdAsync(int userId)
{
var result = await userTable.GetUserByIdAsync(userId) as TUser;
if (result != null)
{
return result;
}
return null;
}
公共异步任务查找
Task<TUser> FindByIdAsync(int userId)
public Task<TUser> FindByIdAsync(int userId)
{
TUser result = userTable.GetUserById(userId) as TUser;
return Task.FromResult<TUser>(result);
}
public async Task<TUser> FindByIdAsync(int userId)
{
TUser result = (await userTable.GetUserByIdAsync(userId)) as TUser;
return result;
}
public Task<TUser> FindByIdAsync(int userId)
{
Task<TUser> result = userTable.GetUserByIdAsync(userId);
return result;
}