【问题标题】:Bulk User Creation in OwinContext (Performance)OwinContext 中的批量用户创建(性能)
【发布时间】:2015-08-23 19:31:01
【问题描述】:

我正在使用 ASP.NET Identity 和 OwinContext 以及 EF 6 将包含所有必需用户的 excel 文件上传到我的网站。 我的代码如下所示:

foreach (var bulkUserDetail in bulkUser.BulkUserDetails)
{

        var userManager = owinContext.GetUserManager<ApplicationUserManager>();

        var userProfile = new UserProfile();

        userProfile.Username = bulkUserDetail.Username;


        AspNetUser newUser = new AspNetUser
        {
            UserName = userProfile.Username,
            Email = bulkUserDetail.Email,
            LastPasswordChangedDate = null,
        };

        var creationResult = userManager.Create(newUser);

        if (creationResult.Succeeded)
        {

            string token = userManager.GeneratePasswordResetToken(newUser.Id);

        }

}

问题是以下两行的表现非常令人失望

userManager.Create(newUser) -- (900 milliseconds)
userManager.GeneratePasswordResetToken(newUser.Id)      --(1800 milliseconds)

大量,即2000个用户,性能成为一个严重的问题。 有没有更好的做法来加快这个过程?我愿意接受建议,但我必须保留 OwinContext 库。

提前致谢

【问题讨论】:

  • 一方面,您在循环中重新获得了 UserManager。这真的有必要吗?我没有查看代码,但如果发生任何延迟加载,可能会减慢速度。
  • 谢谢大卫。它有很大帮助。我还为整个上传块使用了一个 Context 对象,它也提高了性能。现在它在大约 20 分钟内加载了 2000 条记录。还有其他想法吗?
  • 在花了一些时间查看源代码之后,如果您死心塌地使用 ApplicationUserManager,我认为您很不走运。没有任何东西支持任何类型的链式上下文或批量用户创建。您最好的选择可能是某种并行化(如下所示),尽管这不一定会给您带来更好的结果。

标签: c# asp.net identity bulk


【解决方案1】:

您可以尝试在并行内创建用户,这可能会加快整体时间,但是这样做有一个问题:

  • CreateGeneratePasswordResetToken 的调用速度很慢,因为它们调用了数据库
  • 并行执行工作会增加对数据库的并发调用次数,这可能会进一步降低速度,这实际上取决于托管数据库的硬件有多好。

    var userManager = owinContext.GetUserManager<ApplicationUserManager>();
    
    Parallel.ForEach (bulkUser.BulkUserDetails, bulkUserDetail => 
    {       
        //Do you really need to make this userProfile as its not used
        var userProfile = new UserProfile();
    
        userProfile.Username = bulkUserDetail.Username;
    
        AspNetUser newUser = new AspNetUser
        {
            UserName = userProfile.Username,
            Email = bulkUserDetail.Email,
            LastPasswordChangedDate = null,
        };
    
        var creationResult = userManager.Create(newUser);
    
        if (creationResult.Succeeded)
        {
    
            string token = userManager.GeneratePasswordResetToken(newUser.Id);
    
        }
    })
    

【讨论】:

  • 谢谢 Mike,我之前考虑过 Parallel,不幸的是 OwinContext 和 EF6 对多线程不太满意,或者我做错了!
猜你喜欢
  • 2021-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多