如何在Asp.Net Core 2.0中添加UserManagerExtension类方法?

时间:2017-10-24 08:16:01

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

我正在将当前项目迁移到核心,在我当前的项目中,我有许多来自Create类的同步方法调用,如FindByIdAddToRole,{{1}}等。但是,尽管在网上进行了彻底的搜索,我仍然无法在核心中找到相同的内容。

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

1 个答案:

答案 0 :(得分:1)

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

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

如果您仍然需要将async方法作为sync运行,出于某种原因,您可以自行阻止它们:

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应用程序来说非常糟糕。

  3. 长而短,没有一种像同步一样运行异步的好方法,你应该尽可能地避免它。异步应该一直是异步的。这确实是MVC中的一个问题,但现在它不是Core。