0

I have the following classes:

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

}

My question is, in the UserStore, in the RegisterUserAsync function, will the UserRegisterModel get added to the DB before the EmailExist function returns or throw an exception?

2
  • 1
    The AuthenticationAccessLayer.RegisterAsync is not actually async. The context.User.Add is not returned, nor is it Task returning...
    – David Pine
    Commented Jan 26, 2017 at 14:48
  • You should also Avoid async void methods
    – stuartd
    Commented Jan 26, 2017 at 14:51

3 Answers 3

2

No, your RegisterUserAsync method will be executed after the EmailExist method returns.

msdn

The await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.
...
An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.

1
  • Okay I think I get it. The method execution after the await is suspended, but the thread is free to execute other, for instance, UI specific stuff. It will not execute after the await until the EmailExist returns a value? Commented Jan 26, 2017 at 14:52
0

It will throw the ValidateException if the email exists, because you are awaiting the EmailExist function.

-1

It will depend on the thread scheduler probably. However, if you define RegisterUserAsync to be something like

    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);
    }

Then RegisterAsync will execute after EmailExist. (notice the Task return type and the await keyword.)

1
  • 1
    Even if the method is async void RegisterAsync still can't run before EmailExist finishes. RegisterUserAsync will simply return before it's done, and not give it's caller (who is not shown) a way of knowing when it's finished.
    – Servy
    Commented Jan 26, 2017 at 14:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.