C# aspnet标识中的异步代码有误导性

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

我需要为AsNetIdentity实现自定义存储提供程序。 我仔细看了一下四周,发现了不少,但我觉得它们都错了


我的理解是,如果您有一个以“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(空);
}
问题?
  • 执行“Task.FromResult”正确吗?我的意思是“Task.FromResult”是否真的变成了同步?它应该是什么

  • 对上述内容进行编码的正确方法是什么?ConfigureWait(false)如何 async应该是“一路向下,包括数据层,以避免死锁”

  • 任何示例代码/代码片段都将不胜感激


    非常感谢您的反馈

    初始代码绝对不是异步的。它看起来是为了应付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;
    }