Подтвердить что ты не робот

Несколько ожиданий против Task.WaitAll - эквивалентно?

Что касается производительности, будут ли эти два метода работать параллельно GetAllWidgets() и GetAllFoos()?

Есть ли какая-то причина использовать один над другим? Кажется, что происходит много сцене с компилятором, поэтому я не понимаю.

============= МетодА: Использование нескольких ожиданий ==================================

public async Task<IHttpActionResult> MethodA()
{
    var customer = new Customer();

    customer.Widgets = await _widgetService.GetAllWidgets();
    customer.Foos = await _fooService.GetAllFoos();

    return Ok(customer);
}

=============== МетодB: Использование Task.WaitAll =====================

public async Task<IHttpActionResult> MethodB()
{
    var customer = new Customer();

    var getAllWidgetsTask = _widgetService.GetAllWidgets();
    var getAllFoosTask = _fooService.GetAllFos();

    Task.WaitAll(new List[] {getAllWidgetsTask, getAllFoosTask});

    customer.Widgets = getAllWidgetsTask.Result;
    customer.Foos = getAllFoosTask.Result;

    return Ok(customer);
}

=====================================

4b9b3361

Ответ 1

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

Второй вариант будет выполняться одновременно, но будет ждать их синхронно (т.е. блокируя поток).

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

Ожидайте обе операции асинхронно с Task.WhenAll:

public async Task<IHttpActionResult> MethodB()
{
    var customer = new Customer();

    var getAllWidgetsTask = _widgetService.GetAllWidgets();
    var getAllFoosTask = _fooService.GetAllFos();

    await Task.WhenAll(getAllWidgetsTask, getAllFoosTask);

    customer.Widgets = await getAllWidgetsTask;
    customer.Foos = await getAllFoosTask;

    return Ok(customer);
}

Обратите внимание, что после Task.WhenAll завершена выполнение обеих задач, которые уже завершены, поэтому их ожидание немедленно завершается.

Ответ 2

Короткий ответ: Нет.

Task.WaitAll блокирует, await возвращает задачу, как только она встречается, и регистрирует оставшуюся часть функции и продолжения.

Метод ожидания "массового", который вы искали, Task.WhenAll, который фактически создает новый Task, который заканчивается, когда выполняются все задачи, переданные функции.

Так же: await Task.WhenAll({getAllWidgetsTask, getAllFoosTask});

Это для блокирующего вопроса.

Также ваша первая функция не выполняет обе функции параллельно. Чтобы заставить это работать с await, вам нужно написать что-то вроде этого:

var widgetsTask = _widgetService.GetAllWidgets();
var foosTask = _fooService.GetAllWidgets();
customer.Widgets = await widgetsTask;
customer.Foos = await foosTask;

Это сделает первый пример очень похожим на метод Task.WhenAll.

Ответ 3

Только ваш второй вариант будет запускать их параллельно. Ваш первый будет ждать каждого вызова в последовательности.

Ответ 4

Как только вы вызовете метод async, он начнет выполнение. Будет ли он выполняться в текущем потоке (и, следовательно, запускается синхронно) или он будет работать async, определить невозможно.

Таким образом, в первом примере первый метод начнет работу, но затем вы искусственно прекратите поток кода с ожиданием. И, таким образом, второй метод не будет вызываться до того, как будет выполнен первый.

Второй пример вызывает оба метода без остановки потока с ожиданием. Таким образом, они потенциально будут работать параллельно, если методы являются асинхронными.