Задача. Когда все с LINQ выберите - PullRequest
0 голосов
/ 28 февраля 2020
long[] orderIds={10,11,12,13};

var orders= new List<Order>();

await Task.WhenAll(orderIds.Select(async (orderId) =>
{
    var orderDetails = await GetOrderDetails(orderId);

    if (orderDetails != null)
        orders.Add(orderDetails);
}));

Я получаю неправильное поведение с этим, после развертывания этого кода на сервере он работает нормально, но на локальном компьютере иногда добавляет все заказы, но иногда пропускает некоторые заказы.

Может кто-нибудь помочь, пожалуйста чтобы замкнуть это, не уверен, что мне не хватает.

Ответы [ 3 ]

3 голосов
/ 28 февраля 2020

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

var tasks = orderIds.Select( orderId => GetOrderDetails(orderId) ).ToList();

Тогда ждите задания:

await Task.WhenAll( tasks );

И вуаля, ваши заказы готовы.

var orders = tasks.Select( t => t.Result ).Where( o => o != null ).ToList();

Кстати, ничего не мутирует, поэтому вы полностью поточнобезопасны без необходимости блокировок (при условии, что GetOrderDetails поточнобезопасен). Это одно из преимуществ функционального подхода к использованию linq и вообще.

0 голосов
/ 28 февраля 2020

Вы должны использовать Microsoft Reactive Framework (он же Rx) - NuGet System.Reactive и добавить using System.Reactive.Linq; - тогда вы можете сделать это:

long[] orderIds = { 10, 11, 12, 13 };

IList<Order> orders = await
    orderIds
        .ToObservable()
        .SelectMany(id => Observable.FromAsync(() => GetOrderDetails(id)))
        .ToList();
0 голосов
/ 28 февраля 2020

Я предполагаю, что блокировка подойдет.

long[] orderIds={10,11,12,13};

var orders= new List<Order>();

await Task.WhenAll(orderIds.Select(async (orderId) =>
{
    var orderDetails = await GetOrderDetails(orderId);

    if (orderDetails != null)
        lock(orders) orders.Add(orderDetails);
}));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...