【问题标题】:How to add UserManagerExtension class methods in Asp.Net Core 2.0?如何在 Asp.Net Core 2.0 中添加 UserManagerExtension 类方法?
【发布时间】:2017-10-24 08:16:01
【问题描述】:

我正在将我当前的项目迁移到核心,并且在我当前的项目中,我有许多来自 UserManagerExtension 类的同步方法调用,例如 CreateFindByIdAddToRole 等。但是尽管在网上进行了彻底的搜索,但我没有能够在核心中找到相同的内容。

在核心 2.0 中是否已弃用?如果不是,命名空间是什么以及如何包含它?

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-core asp.net-core-2.0


    【解决方案1】:

    据我所知,他们已经走了。然而,他们的存在甚至在以前就受到怀疑。所有扩展所做的只是简单地“同步”运行异步版本,这基本上意味着它们分离了一个在异步调用上阻塞直到完成的任务。虽然这在技术上满足了“同步”方法,但实际上对于 Web 应用程序来说真的很糟糕,因为您要牺牲池中的线程来同步完成工作。

    在 ASP.NET MVC 中,这是一个必要的邪恶,因为有很多方面不支持异步:子操作、操作过滤器等​​。但是,在 Core 中,一切都是异步的,并且事情发生在一个Web 应用程序空间应该是异步的。因此,根本没有充分的理由使用同步方法,这可能就是它们不再存在的原因。

    如果您仍然需要将异步方法作为同步运行,出于某种原因,您可以简单地自己阻止它们:

    var user = UserManager.FindByIdAsync(id).GetAwaiter().GetResult();
    

    但请注意,由于上下文转换,在某些情况下可能会出现死锁。避免这种情况的两种方法是:

    1. 使用ConfigureAwait(false)

      var user = UserManager.FindByIdAsync(id).ConfigureAwait(false).GetAwaiter().GetResult();
      

      但是,您不能在动作方法之类的东西中使用ConfigureAwait(false),因为必须维护上下文才能完成响应。不过,您可以在 action 方法调用的方法中使用它:

      private ApplicationUser GetUser(string id)
      {
          return UserManager.FindByIdAsync(id).ConfigureAwait(false).GetAwaiter().GetResult();
      }
      
      ...
      
      var user = GetUser(id);
      
    2. 在不同的线程中运行它

      Task.Run(() => {
          var user = UserManager.FindByIdAsync(id).GetAwaiter().GetResult();
          // code here that needs `user`
      });
      

      如您所见,使用这种方法,您发送的工作必须是独立的,因此在大多数情况下可能不太适合。同样,这对 Web 应用程序来说非常不利。

    总而言之,没有真正的好方法来运行异步作为同步,你应该尽可能避免它。异步应该一直是异步的。这在 MVC 中确实是一个问题,但现在不在 Core 中了。

    【讨论】:

    • 我猜他们一定是被杀了。但它就这样悄无声息地消失了,没有任何明确的文件使它成为一个阴谋:P 非常感谢您的确认和如此出色的答案
    猜你喜欢
    • 2019-01-17
    • 1970-01-01
    • 2018-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    相关资源
    最近更新 更多