2015-11-05 2 views
1

Я хочу обновить несколько объектов db, используя EF async. У меня естьЗадача WhenВсе правильное использование

[HttpPost] 
    public ActionResult Update(StudentViewModel[] studentData) 
    { 
     try 
     { 
      IEnumerable<Task> tasksQuery = studentData.Select(async s => await UpdateStudentData(s)); 

      List<Task> tasks = tasksQuery.ToList(); 

      Task.WhenAll(tasks); 

      return Json(new { success = true }); 
     } 
     catch (EntityCommandExecutionException ex) 
     { 
      log.Warn(string.Format("{0}: {1}", "Operation Failed", ex.ToString())); 
      return Json(new { success = false }); 
     } 
    } 

    private async Task UpdateStudentData(StudentViewModel sm) 
    { 
     var student= db.Students.FindAsync(sm.Id); 
     if (student.Result != null) 
     { 
      student.Result.SectionId = sm.SectionId; 
      student.Result.PreferenceOrder = sm.PreferenceOrder ; 
      db.Entry(student.Result).State = EntityState.Modified; 
      await db.SaveChangesAsync(); 
     } 
    } 

Требуется только одна операция. Что я делаю не так? Я хочу обновить все сущности, а не последовательно.

+0

Я думаю, что моя проблема на "var student = db.Stud ents.FindAsync (sm.Id);». Он входит только в (student.Result! = Null) один раз, но если он последовательно запускается один за раз, он каждый раз ударяет. –

ответ

1

Игнорируйте и увидеть обновление

[HttpPost] 
    public async Task<ActionResult> Update(StudentViewModel[] studentData) //notice async in this line 
    { 
     try 
     { 
      IEnumerable<Task> tasksQuery = studentData.Select(async s => await UpdateStudentData(s)); 

      List<Task> tasks = tasksQuery.ToList(); 

      await Task.WhenAll(tasks); //Notice await here 

      return Json(new { success = true }); 
     } 
     catch (EntityCommandExecutionException ex) 
     { 
      log.Warn(string.Format("{0}: {1}", "Operation Failed", ex.ToString())); 
      return Json(new { success = false }); 
     } 
    } 

    private async Task UpdateStudentData(StudentViewModel sm) 
    { 
     var student= db.Students.FindAsync(sm.Id); 
     if (student.Result != null) 
     { 
      student.Result.SectionId = sm.SectionId; 
      student.Result.PreferenceOrder = sm.PreferenceOrder ; 
      db.Entry(student.Result).State = EntityState.Modified; 
      await db.SaveChangesAsync(); 
     } 
    } 

Update - Я создал ниже образец кода и протестировал его

[HttpGet] 
public async Task<JsonResult> Update() //notice async in this line and I have changed the return type 
{ 
    try 
    { 
     var id = 0; 
     //Create random data 
     StudentViewModel[] studentData = new StudentViewModel[] { 
     new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, 
     new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, 
     new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ }, new StudentViewModel { ID = id++ } 
     }; 
     IEnumerable<Task> tasksQuery = studentData.Select(s => UpdateStudentData(s)); //Note there is no async and await in this line 

     List<Task> tasks = tasksQuery.ToList(); 

     await Task.WhenAll(tasks); //Note await here 

     return Json(new { success = true }); 
    } 
    catch (Exception ex) 
    { 
     //log.Warn(string.Format("{0}: {1}", "Operation Failed", ex.ToString())); 
     return Json(new { success = false }); 
    } 
} 

private async Task UpdateStudentData(StudentViewModel sm) 
{ 
    await Task.Run(() => 
    { 
     var sleepDelay = new Random().Next(500, 1000); 
     Task.Delay(sleepDelay); //Add random sleep to prove that students are not processsesd in a sequence 
     Debug.WriteLine($"ID: {sm.ID}, SleepDelay: {sleepDelay}"); 
    });   
} 

public class StudentViewModel 
{ 
    public int ID { get; internal set; } 
} 

А ниже был вывод, обратите внимание на ID не последовательные :)

ID: 0, SleepDelay: 868 
ID: 1, SleepDelay: 868 
ID: 3, SleepDelay: 787 
ID: 4, SleepDelay: 966 
ID: 2, SleepDelay: 868 
ID: 6, SleepDelay: 743 
ID: 7, SleepDelay: 661 
ID: 8, SleepDelay: 520 
ID: 9, SleepDelay: 520 
ID: 10, SleepDelay: 520 
ID: 11, SleepDelay: 520 
ID: 5, SleepDelay: 564 
+0

Ваш ответ верный, однако я обнаружил, что DbContext не является потокобезопасным. Вот почему я получал сомнительное исполнение. –

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