Как параллельно обрабатывать несколько асинхронных задач цикла foreach

Как я могу одновременно обрабатывать несколько задач в каждом цикле forach, isconnected устанавливается вызовом await item.GetIsConnected(). На данный момент обновление идет медленно, поэтому я хотел бы, чтобы они обрабатывались одновременно.

До:

private async void Refresh()
{
    foreach (var item in Cars.ToList<Carnet>())
    {
        await item.GetIsConnected();
        if (item.IsConnected)
        {
            await item.GetCarDetailsAsync();
        }
    }
}

После:

private async void Refresh()
{
    List<Task> listOfTasks = new List<Task>();
    foreach (var item in Cars.ToList<Carnet>())
    {
        listOfTasks.Add(item.GetIsConnected());
        if (item.IsConnected)
        {
            await item.GetCarDetailsAsync();
        }
    }
    await Task.WhenAll(listOfTasks);
}

Вы сделали какое-либо профилирование, чтобы проверить, что на самом деле работает медленно? Если это какой-то API, который вы запрашиваете, вы, вероятно, получите лучшую производительность с меньшими усилиями, если запрос позволит вам получать данные для нескольких автомобилей одновременно.

JonasH 16.05.2022 22:55

@JonasH Каждая итерация извлекает данные с защитного IP-адреса. это не очень медленно. что я имею в виду. Он извлекается с IP-адреса 1, проверяя детали соединения, затем второй IP-адрес начинается после завершения IP 1 ... и так далее, вместо этого я хотел бы, чтобы IP 1 и 2 начали обработку одновременно

Dev 16.05.2022 22:59

Как метод item.GetIsConnected() связан со свойством item.IsConnected?

Theodor Zoulias 16.05.2022 22:59

@TheodorZoulias item.GetIsConnected() обновляет item.IsConnected

Dev 16.05.2022 23:01

Поэтому, если вы вызовете IsConnected до завершения асинхронного GetIsConnected(), вы можете получить неверный результат. Что делает свойство IsConnected ненадежным, я прав?

Theodor Zoulias 16.05.2022 23:05

@TheodorZoulias да.

Dev 16.05.2022 23:08
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
0
6
41
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку вы не ожидаете вызова GetIsConnected() в вашем примере ПОСЛЕ, цикл будет продолжаться, и значение не будет сравниваться с тем, что было бы после завершения вызова GetIsConnected(), я думаю, что вы хотели бы сделать, это добавить еще один метод с типом возвращаемого значения Task и пусть метод вызывает GetIsConnected() и await его внутри метода, а затем вызывает GetCarDetailsAsync() при необходимости:

//changed to return type of Task, as async void should be avoided
//unless this is an event handler method
private async Task Refresh()
//private async void Refresh() //change to this if event handler
{
    List<Task> listOfTasks = new List<Task>();
    foreach (var item in Cars.ToList<Carnet>())
    {
        listOfTasks.Add(GetCarDetails(item));        
    }
    await Task.WhenAll(listOfTasks).ConfigureAwait(false);
}

//method to await the call to GetIsConnect() 
//and then call GetCarDetailsAsync() if necessary
private async Task GetCarDetails(Carnet c)
{
    await c.GetIsConnected();
    if (c.IsConnected)
    {
        await c.GetCarDetailsAsync();
    }
}

Другие вопросы по теме