在我的ASP.Net MVC 5项目中,我有一个自定义初始化类:
class CustomInitializer : DropCreateDatabaseIfModelChanges<GhazanetContext>
我想为几个用户播种上下文。问题是新的MVC 5是async
,无论我尝试做什么都失败了。这是我尝试创建用户的代码:
private void AddRestaurant(RegisterRestaurantViewModel model, DBContext db)
{
User user = new User(model.UserName) { Addresses = new List<Address>(), Role = "Restaurant" };
user.Addresses.Add(model.Address);
Task.Factory.StartNew(async () =>
{
await Users.Create(user); // GETS STUCK HERE
var newUser = db.Users.Where(u => u.UserName == user.UserName).FirstOrDefault();
var restaurant = new Restaurant(model) { User = newUser };
db.Restaurants.Add(restaurant);
db.SaveChanges();
await Secrets.Create(new UserSecret(model.UserName, model.Password));
await Logins.Add(new UserLogin(user.Id, IdentityConfig.LocalLoginProvider, model.UserName));
const string role = "Restaurant";
if (!await Roles.RoleExists(role))
await Roles.CreateRole(new Role(role));
await Roles.AddUserToRole(role, user.Id);
}).RunSynchronously();
}
}
当我运行此代码时,它会卡在上面的行中,但是当我在网站上运行它并注册用户时,它运行得很好。这里有什么我想念的吗?
答案 0 :(得分:1)
您正在使用Task.Factory.StartNew
和ExecuteSynchronously
,async
代码中都不应使用这两种代码。
调用async
代码的最佳方法是从 async
代码中调用,如下所示:
private async Task AddRestaurantAsync(RegisterRestaurantViewModel model, DBContext db)
{
User user = new User(model.UserName) { Addresses = new List<Address>(), Role = "Restaurant" };
user.Addresses.Add(model.Address);
await Users.Create(user);
var newUser = db.Users.Where(u => u.UserName == user.UserName).FirstOrDefault();
var restaurant = new Restaurant(model) { User = newUser };
db.Restaurants.Add(restaurant);
db.SaveChanges();
await Secrets.Create(new UserSecret(model.UserName, model.Password));
await Logins.Add(new UserLogin(user.Id, IdentityConfig.LocalLoginProvider, model.UserName));
const string role = "Restaurant";
if (!await Roles.RoleExists(role))
await Roles.CreateRole(new Role(role));
await Roles.AddUserToRole(role, user.Id);
}
这确实会通过您的代码库产生级联效果(AddRestaurantAsync
的调用者必须自己为async
等),但这是调用async
代码最简单,最干净的方式。存在各种乱码以同步方式调用异步代码,但很容易陷入死锁情况,即使你做对了也会影响你网站的可扩展性。
答案 1 :(得分:0)
您可以同步运行异步任务:var result = Users.Create(user).Result