【问题标题】:How to use UserManager synchronously? [duplicate]如何同步使用 UserManager? [复制]
【发布时间】:2015-12-27 03:13:05
【问题描述】:

在给定我的DbContextSeed 方法中,我的IDatabaseInitializer 之一将初始数据插入数据库。除其他外,还有一些用户需要初始化。但就我使用 Microsoft.AspNet.Identity.EntityFramework.UserStoreMicrosoft.AspNet.Identity.UserManager 而言,它具有 only 异步方法,它使 DbUpdateConcurrencyException 如下:

private static void CreateUser(DbContext context, string[] roles, string userName, string userEmail) {

    // given context is 
    var user = new ApplicationUser { /* ... fields init */  };

    var userStoreAdapter = new ApplicationUserRepository(context);
    var manager = new UserManager<ApplicationUser>(userStoreAdapter);

    // pass the creation to manager by calling it synchronously. See UserManagerExtensions
    manager.Create(user, Domain.Constants.DefaultPassword);
    manager.AddToRoles(user.Id, roles);

    context.SaveChanges(); // throws DbUpdateConcurrencyException. See another approach below.
}

那么问题是,是否有一种方法可以将UserManagerDbContext 一起使用而不会出现并发问题?

我尝试了从Optimistic Concurrency Patterns 获取的以下方法,但这不会创建用户:

bool isSaved = true;
do
{
    try
    {
        context.SaveChanges();
        isSaved = true;
    }
    catch (DbUpdateConcurrencyException ex)
    {
        foreach (var entry in ex.Entries)
        {
            entry.Reload();
        }
        isSaved = false;
    }
} while (!isSaved);

【问题讨论】:

  • 我认为您的问题可以分解为“如何从同步方法调用异步方法?”如果是这样,这可能会对您有所帮助:stackoverflow.com/questions/22628087/…
  • @NathanA Task 总是在另一个线程中运行,对吧?所以UserManager 更新数据库,而给定的DbContext 不知道它。它与上述并发异常中断。那么我可以在当前线程中运行它吗?该帖子看起来没有帮助。由UserManager 的扩展方法调用的AsyncHelper 执行类似的操作。
  • 我相信我也有同样的问题。在我的情况下,客户端启动了一个冗长的数据库脚本,服务器的响应是 200 OK。但是在漫长的过程完成后,我尝试运行 _RoleManager.CreateAsync 并且没有任何反应。你找到工作了吗? @Artyom?

标签: c# entity-framework asp.net-identity


【解决方案1】:

要同步使用 UserManager,您需要从 System.Threading.Tasks 调用 .GetAwaiter().GetResult() 扩展方法。例如使用用户管理器同步获取当前用户:

using System.Threading.Tasks;
var currentUser = _userManager.GetUserAsync(User).GetAwaiter().GetResult();

这两个来自 System.Threading.Tasks 命名空间的扩展方法获取任务的等待者 GetUsersAsync() 并获取结果。

【讨论】:

  • async 关键字不会让您的代码并行运行。它所做的只是在等待 I/O 操作完成时释放线程。所以这里不是这样
  • 如果您检查上面的 CreateUser 方法,它是一个同步方法,并且用户希望在同步方法中使用 UserManager 而不是并行运行代码,如果他们没有在问题
  • OP 的代码中没有异步方法调用。他们没有正确描述他们的问题。
  • 转换用户对象对我有用,因此获得了投票
  • GetAwaiter().GetResult() 对我不起作用。 _userManager.GetUserAsync(User).Result 也对我不起作用。
【解决方案2】:
var result = Task.Run(() => {
   /*whatever you want here*/
}).Result;

// Do whatever u want with the result after

【讨论】:

    猜你喜欢
    • 2013-10-18
    • 2019-01-04
    • 2017-11-27
    • 1970-01-01
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-09-09
    • 2022-10-24
    相关资源
    最近更新 更多