在上一个操作完成之前,在此上下文中开始第二个操作。接口上的异步方法

时间:2018-03-08 14:42:42

标签: c# asp.net-mvc async-await

当我从我实现的界面尝试SaveChangesAsync()时,我收到错误。此接口上的每个其他方法似乎都可以正常工作。我在发出错误的每个任务和每个IsCompleted之前调试了每个任务。我是新手,所以告诉我这里我做错了什么。

UserController只是构造函数

private readonly IUserRepository _userRepository;
private readonly IRoleRepository _roleRepository;

public UserController(IUserRepository userRepository,IRoleRepository roleRepository)
{
      _userRepository = userRepository;
      _roleRepository = roleRepository;
}

UserController/Edit

public async Task<IActionResult> Edit(string id, EditViewModel model)
        {
            ApplicationUser user = new ApplicationUser();
            List<IdentityRole> listaRoles = new List<IdentityRole>();
            IdentityRole Role = new IdentityRole();
            List<IdentityRole> listaSelectedRoles = new List<IdentityRole>();

            //Atribuir o nomeUtilizador ao modelo do Post
            var modelTemp = await base.CreateModel<EditViewModel>(_userRepository);
            Task taskModel = base.CreateModel<EditViewModel>(_userRepository);
            await Task.WhenAll(taskModel);
            bool test = taskModel.IsCompleted; //to debug: test = true;

            model.NomeUtilizador = modelTemp.NomeUtilizador;
            modelTemp = null;

            //buscar o utilizador com o id à base de dados
            user = await _userRepository.FindByIDAsync(id);
            var boo = _userRepository.FindByIDAsync(id).IsCompleted;    //to debug: boo = true;

            //Buscar roles da bd para uma lista
            var task = _roleRepository.ToListAsync();
            listaRoles = await task;
            var t = task.IsCompleted; //to debug: t = true;

            (...)

            if (ModelState.IsValid)
            {
                try
                {
                    (...)
                    //Adicionar/remover roles a cada utilizador
                    foreach (var role in listaRoles)
                    {
                        await _userRepository.RemoveFromRoleAsync(user, role.Name); //tested here: true aswell

                        foreach(var selectedRole in listaSelectedRoles)
                        {
                            if (role.Id == selectedRole.Id)
                            {
                               await _userRepository.AddToRoleAsync(user, selectedRole.Name);   //tested here: true aswell
                            }
                        }
                    }
                    user.Nome = model.Nome;
                    user.Email = model.Email;
                    user.UserName = model.Email;
                    user.PhoneNumber = model.Telemovel;

                    await _userRepository.UpdateAsync(user); //error
                }
                catch (DbUpdateConcurrencyException)
                {
                    if (!await ApplicationUserExists(user.Id))
                    {
                        return NotFound();
                    }
                    else
                    {
                        throw;
                    }
                }
                return RedirectToAction(nameof(Index));
            }
            return View(model);
        }

IUserRepository

public interface IUserRepository : IDisposable
    {
        Task<List<ApplicationUser>> ToListAsync();
        Task<ApplicationUser> FindByIDAsync(string userId);
        Task<ApplicationUser> FindByNameAsync(string userName);
        Task<IList<string>> GetRolesAsync(ApplicationUser user);
        Task AddToRoleAsync(ApplicationUser user, string roleName);
        Task RemoveFromRoleAsync(ApplicationUser user, string roleName);
        Task<bool> AnyAsync(string userId);
        Task AddAsync(ApplicationUser user);
        Task DeleteAsync(string userId);
        void Update(ApplicationUser user);
        Task SaveChangesAsync();
        Task UpdateAsync(ApplicationUser user);
    }

UserRepository并非所有节省空间的方法

public class UserRepository : IUserRepository
    {
        private readonly ApplicationDbContext _context;
        private readonly UserManager<ApplicationUser> _userManager;

        public UserRepository(ApplicationDbContext context, UserManager<ApplicationUser> userManager)
        {
            _context = context;
            _userManager = userManager;
        }

        public Task<ApplicationUser> FindByIDAsync(string userId)
        {
            return _context.ApplicationUser.FindAsync(userId);
        }

        public Task<ApplicationUser> FindByNameAsync(string userName)
        {
            return _context.ApplicationUser.SingleOrDefaultAsync(m => m.UserName == userName);
        }

        public Task<List<ApplicationUser>> ToListAsync()
        {
            return _context.ApplicationUser.ToListAsync();
        }

        public Task AddAsync(ApplicationUser user)
        {
            _context.ApplicationUser.AddAsync(user);
            return _context.SaveChangesAsync();
        }

        public Task<IList<string>> GetRolesAsync(ApplicationUser user)
        {
            return _userManager.GetRolesAsync(user);
        }

        public Task AddToRoleAsync(ApplicationUser user, string roleName)
        {
            _userManager.AddToRoleAsync(user, roleName);
            return _context.SaveChangesAsync();
        }

        public Task RemoveFromRoleAsync(ApplicationUser user, string roleName)
        {
            _userManager.RemoveFromRoleAsync(user, roleName);
            return _context.SaveChangesAsync();
        }



        public Task UpdateAsync(ApplicationUser user)
        {
            _context.Entry(user).State = EntityState.Modified;
            return _context.SaveChangesAsync();
        }
    }

就像我说的那样,我调试了所有其他方法及其:Status = RanToCompletion。 谢谢。

2 个答案:

答案 0 :(得分:3)

您的“存储库”中有多个方法可以启动异步操作,但不要等待它们完成。所以你需要修复这些方法:

public async Task AddAsync(ApplicationUser user)
{
    // need to await this one
    await _context.ApplicationUser.AddAsync(user);
    await _context.SaveChangesAsync();
}

public async Task AddToRoleAsync(ApplicationUser user, string roleName)
{
    // same story
    await _userManager.AddToRoleAsync(user, roleName);
    await _context.SaveChangesAsync();
}

public async Task RemoveFromRoleAsync(ApplicationUser user, string roleName)
{
    // same story
    await _userManager.RemoveFromRoleAsync(user, roleName);
    await _context.SaveChangesAsync();
}

答案 1 :(得分:1)

尝试在 UserRepository

上更改此设置
    public Task UpdateAsync(ApplicationUser user)
    {
        _context.Entry(user).State = EntityState.Modified;
        return _context.SaveChangesAsync();
    }

为此,返回 _context.SaveChangesAsync()的int值

    public async Task<int> UpdateAsync(ApplicationUser user)
    {
            _context.Entry(user).State = EntityState.Modified;
            return await _context.SaveChangesAsync();               
    }