2013-09-04 3 views
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(); 
    } 
} 

Когда я запускаю этот код, он застревает в строке выше, но когда я запускаю его на сайте и регистрации пользователей, он прекрасно работает. Здесь что-то не хватает?

+0

у вас есть опечатка для «застрял», это не «акции» – DarthVader

+0

@DarthVader LOL. Благодарю. Это то, что происходит, когда вы отправляете вопрос между двумя частями вашего сна: D BTW, я был в запасах в то время, может быть, именно поэтому! –

+0

Это действительно компилируется? У встроенных классов 'Users' /' Roles' нет методов async. –

ответ

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. Существуют различные хаки для синхронного вызова асинхронного кода, но легко попасть в тупиковые ситуации, и даже если вы это исправите, это повлияет на масштабируемость вашего сайта.

+0

Спасибо. Проблема была не в том, что я не знал, как использовать 'async'. Я пытался запустить методы async, такие как' Users.Create (user); 'синхронно. Однако, когда я прочитал ваш ответ, мне пришло в голову, что я искренне вернусь к типу события, что thandler функции 'Seed' является' void', я мог бы отметить его как 'async', не меняя его подписи, но работает. Однако по какой-то причине я получить сообщение об ошибке после инициализации базы данных. Это полностью функционально, хотя это не так много проблем. Еще раз спасибо. –

+0

@AlirezaNoori: Вам также следует избегать «async void», если это абсолютно необходимо. Рекомендую вам связаться с командой EF и спросить их что рекомендуемая практика: –

+0

Хммм. Вы знаете метод прямого контакта, как твиттер некоторых из разработчиков? Каков ваш рекомендуемый способ связаться с ними? –

0

Вы можете запустить асинхронную задачу синхронно: var result = Users.Create(user).Result

Смежные вопросы