C# 与异步/等待函数流混淆
我有以下课程: 数据访问工厂:C# 与异步/等待函数流混淆,c#,asynchronous,async-await,C#,Asynchronous,Async Await,我有以下课程: 数据访问工厂: public class DataAccessFactory { public static IUserAccessLayer User() => new UserAccessLayer(new DataContext()); public static IAuthenticationAccessLayer Authentication() => new AuthenticationAccessLayer(new DataAccess.
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;
}
}
用户存储:
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中的RegisterUserSync函数中,UserRegisterModel是否会在EmailExist函数返回或引发异常之前添加到DB中?这可能取决于线程调度程序。但是,如果将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之后执行。请注意任务返回类型和wait关键字。如果电子邮件存在,它将抛出ValidateException,因为您正在等待EmailExist函数。否,您的RegisterUserAsync方法将在EmailExist方法返回后执行 wait运算符应用于异步方法中的任务,以 暂停方法的执行,直到等待的任务完成。 这项任务是正在进行的工作。 ... 等待表达式不会阻止它所在的线程 执行。相反,它会导致编译器注册程序的其余部分 异步方法作为等待的任务的延续。那么控制 返回异步方法的调用方。当任务完成时,它将 调用它的延续,异步方法的执行继续 在它停止的地方
即使该方法是async void RegisterAsync,也无法在EmailExist完成之前运行。RegisterUserAsync只会在完成之前返回,而不会给它的调用方提供一种不知道何时完成的方法。AuthenticationAccessLayer.RegisterAsync实际上不是异步的。context.User.Add没有返回,任务也没有返回…你也应该知道,我想我明白了。等待之后的方法执行被挂起,但线程可以自由执行其他,例如,特定于UI的内容。它将不会在等待后执行,直到EmailExist返回值?