sterenas Ответов: 1

Winforms - запуск нескольких асинхронных функций и ожидание завершения последней из них


Привет!
Мы совершенствуем наши VB.NET решение путем Асинхронизации большинства функций. Добавление Async/Await теперь довольно просто, но мы не знаем, как поступить со следующим.
При запуске приложения мы предварительно заполняем несколько (10) таблиц данных из базы данных SQL Azure (у нас есть индикатор выполнения, который увеличивает свое значение по мере выполнения каждой функции синхронизации). Мы можем добавить Async/Await для каждой функции, но мы подумали, что можем попробовать запустить их все одновременно и просто дождаться завершения последней из них, прежде чем продолжить (думали, что это ускорит время загрузки). Все функции являются командами SQL SELECT.
Мы довольно много читали об этом, но на самом деле не нашли того, что нам нужно. Я думал, что мы можем использовать только Async/Await и никаких фоновых рабочих или задач.
Объединение 10 функций синхронизации в 1 асинхронную функцию не является решением, поскольку нам все еще нужно запускать их по отдельности позже.
Как бы вы поступили и прибили это к ногтю? Очень ценю ваши комментарии.
Спасибо!
Серджио

Что я уже пробовал:

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

1 Ответов

Рейтинг:
1

Afzaal Ahmad Zeeshan

Цитата:
просто подождите, пока последний закончит
Это немного запутанное утверждение. Как сказать, который из них последний? Есть ли у вас ссылка на последнюю переменную в переменной задачи? Или у вас есть их список, и вы просто хотите посмотреть, когда все они будут завершены? Ну, и то, и другое можно легко решить с помощью TPL (Task Parallel Library).
var lastTask = something;

// When all is scheduled
lastTask.Wait(); 

// Or await lastTask if the function is async.
Это будет ждать только последней задачи, если какие-либо другие задачи находятся в ожидании, то она будет пропущена. Однако лучшей альтернативой является то, чтобы иметь List<Task> и у вас есть Task функция для WhenAll быть призванным на него.
var list = allTasks;

Task.WhenAll(list).Wait(); // or await Task.WhenAll(list);
Вы уже используете шаблон async/await, поэтому знаете, что подход async и await лучше. Но почему-то вы тоже, кажется, немного запутались в этом,
Цитата:
Я думал, что мы можем использовать только Async/Await и никаких фоновых рабочих или задач.
Шаблон Async/await в C# основан на задаче (System.Нарезание резьбы.Пространство имен задач). Итак, я не думаю, что вы можете применить что-либо с помощью async/await и пропустить Task тип. :-)

Задача.Метод WhenAll (System.Нарезание резьбы.Задачи) | Microsoft Docs[^]
Цитата:
10 выбирает одновременно.
Это похоже на 10 новых запросов к базе данных SQL Azure, 10 подключений (хотя серверная часть может использовать пул подключений), а затем накладные расходы на потоки, пулы потоков и переключение контекста. Я не уверен, как это могло бы улучшить общее время запуска и производительность. Да, он может улучшить отзывчивость и масштабируемость, а также использовать потоки пула потоков, но все же. 10 команд SELECT займут столько же времени, сколько и в версии sync, но да, создание ресурсов будет намного дешевле при асинхронном подходе.


sterenas

Спасибо Afzaal! Под "последней задачей" я подразумеваю "самую медленную задачу" или ту, которая может занять больше времени для выполнения в определенное время.
Даже если мы только улучшим отзывчивость и масштабируемость, это уже быстрая победа, но я все равно надеюсь, что он должен запускать 10 вариантов одновременно, а не последовательно, верно ?
Использование пула соединений в базе данных SQL Azure и большого количества доступных DTU.
Вы все еще говорите, что мы не должны замечать прирост производительности?
Спасибо!
Серджио

Afzaal Ahmad Zeeshan

Тогда метод списка должен работать для вас.

Я говорил о синхронизации/асинхронном подходе. Это тоже зависит от самого приложения, что это за приложение? В случае веб-приложения асинхронный подход может увеличить масштабируемость в несколько раз. Но помните, что каждая операция сама по себе займет столько времени, сколько она потребует.

Другими словами, приложение будет более эффективно обрабатывать запросы и генерировать ответы. Но общее время запроса останется неизменным, поскольку асинхронность не гарантирует более быстрого выполнения кода.

BillWoodruff

+5

Afzaal Ahmad Zeeshan

Спасибо, Билл.