【问题标题】:Why use Task.FromResult<T>(T result) from a method that contains awaits?为什么从包含等待的方法中使用 Task.FromResult<T>(T result)?
【发布时间】:2020-05-25 13:01:51
【问题描述】:

我在教程中遇到了以下方法;

    private async Task<ClaimsIdentity> GetClaimsIdentity(string userName, string password)
    {
        if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
            return await Task.FromResult<ClaimsIdentity>(null);

        // get the user to verifty
        var userToVerify = await _userManager.FindByNameAsync(userName);

        if (userToVerify == null) return await Task.FromResult<ClaimsIdentity>(null);

        // check the credentials
        if (await _userManager.CheckPasswordAsync(userToVerify, password))
        {
            return await Task.FromResult(_jwtFactory.GenerateClaimsIdentity(userName, userToVerify.Id));
        }

        // Credentials are invalid, or account doesn't exist
        return await Task.FromResult<ClaimsIdentity>(null);
    }

作者总是使用await Task.FromResult&lt;ClaimsIdentity&gt;(...),即使返回null。我不是 Task-await 模式的专家,我会编写类似这样的方法;

    private async Task<ClaimsIdentity> GetClaimsIdentity(string userName, string password)
    {
        if (string.IsNullOrEmpty(userName) || string.IsNullOrEmpty(password))
            return null;

        // get the user to verifty
        var userToVerify = await _userManager.FindByNameAsync(userName);

        if (userToVerify == null) return null;

        // check the credentials
        if (await _userManager.CheckPasswordAsync(userToVerify, password))
        {
            return _jwtFactory.GenerateClaimsIdentity(userName, userToVerify.Id);
        }

        // Credentials are invalid, or account doesn't exist
        return null;
    }

两者都编译。这两种方法有什么区别(如果有的话)?以这种方式使用await Task.FromResult&lt;ClaimsIdentity&gt;(null)有什么好处吗?

【问题讨论】:

  • 这是浪费可打印字符和冗余代码的完美示例。更不用说可能是另一个IAsyncStateMachine 实现
  • 你问过代码作者同样的问题吗?
  • 这会围绕已经完成的结果构造一个新任务,所以不,在这种情况下使用 Task.FromResult 没有意义。此方法用于返回任务的非异步方法。
  • 你可以在这里查看the difference
  • await Task.FromResult 除了浪费 CPU 周期外什么都不做。 PS:显然这段代码的来源是fullstackmark.com/post/13/…,它可能是通过将非异步方法自动重构为异步方法而创建的,因为作者使用其他地方的异步方法中的普通returns。

标签: c# .net-core async-await


【解决方案1】:

根据我找到的关于 Task.FromResult 的最佳 stackoverflow 答案:https://stackoverflow.com/a/19696462/6440521

Task.FromResult 的使用仅适用于同步方法和模拟的上下文。因此,当您只想返回结果时,在 async 方法中使用它是多余的 - 不会给您带来额外的好处,AsyncGuidance 也没有说明在中使用 Task.FromResult async 方法: https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md

因此,在 async 方法中使用 Task.FromResult 的 AFAIK 是不必要的,它会使您的代码膨胀并且不会给您带来任何实际好处。

【讨论】:

  • 是什么让这个答案成为“最好的 stackoverflow 答案”?
  • 这个答案的作者是 Stephen Cleary
  • 虽然斯蒂芬拥有大量知识,但将其标记为“最好的 stackoverflow 答案”是一个大胆的声明。 stackoverflow 上有数千个甚至数十万个答案。
  • @BART 感谢您的回答,您确实说这是您发现的与此特定问题相关的最佳答案,并不是说这是所有问题的最佳答案堆栈溢出。您还对他人给予了应有的认可,并提供了原始来源的链接。
  • @mark_h 请注意我的 cmets 是关于以前版本的答案。
猜你喜欢
  • 2020-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多