0

在我的 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();
    }
}

当我运行此代码时,它卡在上面的行中,但是当我在网站上运行它并注册用户时,它运行良好。我在这里缺少什么吗?

4

2 回答 2

1

您正在使用Task.Factory.StartNewand 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);
}

这确实会在您的代码库中产生级联效应(AddRestaurantAsyncmust 的调用者自己是async等),但它是调用async代码的最简单和最干净的方式。以同步方式调用异步代码存在各种技巧,但很容易陷入死锁情况,即使你做对了,它也会影响你网站的可伸缩性。

于 2013-09-04T11:47:30.863 回答
0

您可以同步运行异步任务:var result = Users.Create(user).Result

于 2013-09-05T13:18:03.993 回答