混淆了异步/等待函数的流程

时间:2017-01-26 14:35:06

标签: c# asynchronous async-await

我有以下课程:

DataAccessFactory:

public class DataAccessFactory
{
    public static IUserAccessLayer User() => new UserAccessLayer(new DataContext());
    public static IAuthenticationAccessLayer Authentication() => new AuthenticationAccessLayer(new DataAccess.DataContext());
}

AuthenticationAccessLayer:

public class AuthenticationAccessLayer : IAuthenticationAccessLayer
{
    private readonly DataContext context;

    public AuthenticationAccessLayer(DataContext context)
    {
        this.context = context;
    }

    public async void RegisterAsync(UserRegisterModel model)
    {
        context.User.Add(new UserModel()
        {
            EmailAddress = model.Email,
            PasswordHash = model.PasswordHash,
            PasswordSalt = model.PasswordSalt
        });
    }

    public async Task<bool> EmailExist(string email)
    {
        var user = await context.User.Where(x => x.EmailAddress.Equals(email)).FirstOrDefaultAsync();
        if (user == null)
            return false;
        else
            return true;
    }
}

UserStore:

public class UserStore : ViewModelBase
{
    public UserStore()
    {
    }

    public UserStore(int userID)
    {
        this.UserID = userID;
    }

    #region Authentication

    public async Task<bool> AuthenticateAsync(LoginModel model)
    {
        return await DataAccessFactory.Authentication().LoginAsync(model);
    }

    public async void RegisterUserAsync(UserRegisterModel model)
    {
        var store = DataAccessFactory.Authentication();

        //check if unique email
        if(await store.EmailExist(model.Email))
            throw new ValidationException($"Email {model.Email} is already registered.");

        store.RegisterAsync(model);
    }

    #endregion

}

我的问题是,在UserStore中,在RegisterUserAsync函数中,UserRegisterModel函数返回或抛出异常之前是否会将EmailExist添加到数据库中?

3 个答案:

答案 0 :(得分:2)

不,您的RegisterUserAsync方法将在EmailExist方法返回后执行。

msdn

  

await运算符应用于异步方法中的任务   暂停方法的执行,直到等待的任务完成。   该任务代表了正在进行的工作   ...
  await表达式不会阻塞它所在的线程   执行。相反,它会导致编译器注册其余部分   异步方法作为等待任务的延续。然后控制   返回异步方法的调用者。当任务完成时,它   调用它的继续,并重新执行异步方法   它停止了。

答案 1 :(得分:0)

如果电子邮件存在,它将抛出ValidateException,因为您正在等待EmailExist功能。

答案 2 :(得分:-1)

它可能取决于线程调度程序。但是,如果您将RegisterUserAsync定义为

    public async Task RegisterUserAsync(UserRegisterModel model)
    {
        var store = DataAccessFactory.Authentication();

        //check if unique email
        if(await store.EmailExist(model.Email))
            throw new ValidationException($"Email {model.Email} is already registered.");

        await store.RegisterAsync(model);
    }

然后RegisterAsync将在EmailExist之后执行。 (注意Task返回类型和await关键字。)