2015-10-16 4 views
0

Я пытаюсь выяснить, как использовать async/await правильно в слое данных моего приложения для параллельного выполнения нескольких запросов к базе данных.Выполнение нескольких запросов Linq Async

Я использую Entity Framework и Linq для выполнения своих данных.

Слой данных можно вызывать из любого типа приложения (MVC Web App, Web API Project, Win From, Windows Service и т. Д.), Поэтому результат метода должен быть единственным объектом.

public static async void GetLedger(long id, DateTime StartDate, DateTime EndDate) 
    { 
     var task_1 = DoComplexDBCallAsync1(); 
     var task_2 = DoComplexDBCallAsync2(); 
     var task_3 = DoComplexDBCallAsync3(); 
     var task_4 = DoComplexDBCallAsync4(); 
     var task_5 = DoComplexDBCallAsync5(); 

     await Task.WhenAll(task_1, task_2, task_3, task_4, task_5); 

     var result = ProcessAndMergeResultsFromAllDBCalls(task_1.Result, task_2.Result, task_3.Result, task_4.Result, task_5.Result); 

     return result; 
    } 

    private static async Task<List<SomeComplexType>> DoComplexDBCallAsync1(long id) 
    { 
     using (var metadata = DataAccess.getDesktopMetadata()) 
     { 
      var accounts = await (from row in metadata.db_GLAccount 
            where row.busID == id 
            select row).ToListAsync(); 

      return accounts; 
     } 
    } 

Как бы я изменить выше, чтобы вернуть один object вместо Task<>?

Должен ли я обернуть его другим методом, который вызывает метод async GetLedger через прогон Task или RunSynchronously() и возвращает результаты? Если да, то как бы выглядел код и есть ли что-нибудь, о чем я должен знать?

Какова наилучшая практика в этом сценарии?

+2

Ответ: ** вы не **. Он должен возвращать «Задачу», а не «пустоту» или возвращать фактический элемент. Это то, что позволяет ему правильно работать асинхронно. Если вы хотите, чтобы он выполнялся синхронно, просто создайте полностью синхронный метод, используя синхронный EF-код до конца. – Servy

+0

Нет. Они должны быть асинхронными и иметь возможность видеть, что этот метод является асинхронным. Использование 'await' делает реализацию этой асинхронности намного проще, но она все еще должна быть там. – Servy

ответ

-1

Вы использовали бы ждать следующий

public static async Task<SomeObject> GetLedger(long id, DateTime StartDate, DateTime EndDate) 
    { 
     var task_1 = DoComplexDBCallAsync1(); 
     var task_2 = DoComplexDBCallAsync2(); 
     var task_3 = DoComplexDBCallAsync3(); 
     var task_4 = DoComplexDBCallAsync4(); 
     var task_5 = DoComplexDBCallAsync5(); 

     var result = ProcessAndMergeResultsFromAllDBCalls(await task_1, await task_2, await task_3, await task_4, await task_5); 

     return result; 
    } 

«ждет» ключевого слова будет автоматически получить результат задачи и применить его к переменным, когда DB вызывает возвращение. MSDN

Вы бы затем вызвать

var result = await GetLedger(id, StartDate, EndDate); 

, который будет продолжаться после того, как все завершено.

+0

Вы изменили метод на тот, который выполняет все 5 операций DB параллельно с тем, который делает их все последовательно, и есть все признаки того, что они должны выполняться параллельно. Он также специально спросил, как получить этот метод * не * вернуть «Задачу». – Servy

+0

Ой, извините. Я поставил ожидаю не в том месте. Ред. – Vlad274

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