выберите из оператора linq с await - PullRequest
3 голосов
/ 25 июня 2019

Кажется, это должно быть очень просто, у меня есть следующий код

var additionalInformation=   response.AdditionalInformation.Select( async x =>  new AdditionalInformationItem
                {
                    StatementCode = x?.StatementCode?.Value,
                    LimitDateTime = x?.LimitDateTime?.Item?.Value,
                    StatementTypeCode = x?.StatementTypeCode?.Value,
                    StatementDescription = x?.StatementDescription?.Value,
                    AdditionalInformationResult = await BuildAdditionalInformationPointers(x)


                }).ToList();

Я пытаюсь добиться того, чтобы дополнительная информация имела тип

List<AdditionalInformationItem>

, чтоЯ получаю List<Task<AdditionalInformationItem>>

Может ли кто-нибудь помочь мне правильно переформулировать мое утверждение?

Ответы [ 3 ]

5 голосов
/ 25 июня 2019

Вам нужно развернуть задачи с помощью await Task.WhenAll(additionalInformation), затем вы получите доступ к фактическому результату с помощью additionalInformation[0].Result.

Так что-то вроде этого:

var additionalInformation=   response.AdditionalInformation.Select( async x =>  new AdditionalInformationItem
                {
                    StatementCode = x?.StatementCode?.Value,
                    LimitDateTime = x?.LimitDateTime?.Item?.Value,
                    StatementTypeCode = x?.StatementTypeCode?.Value,
                    StatementDescription = x?.StatementDescription?.Value,
                    AdditionalInformationResult = await BuildAdditionalInformationPointers(x)


                });

await Task.WhenAll(additionalInformation);
//This will iterate the results so may not be the most efficient method if you have a lot of results
List<AdditionalInformationItem> unwrapped = additionalInformation.Select(s => s.Result).ToList();
1 голос
/ 25 июня 2019

await Task.WhenAll автоматически развернет задачи и передаст вам массив с результатами.

AdditionalInformationItem[] additionalInformation = await Task.WhenAll(
    response.AdditionalInformation.Select(async x => new AdditionalInformationItem
    {
        StatementCode = x?.StatementCode?.Value,
        LimitDateTime = x?.LimitDateTime?.Item?.Value,
        StatementTypeCode = x?.StatementTypeCode?.Value,
        StatementDescription = x?.StatementDescription?.Value,
        AdditionalInformationResult = await BuildAdditionalInformationPointers(x)
    });
);
0 голосов
/ 25 июня 2019

На самом деле нет способа сделать это в простом лямбда-выражении. Асинхронное лямбда-выражение всегда будет возвращать Task<T>. Таким образом, вы можете пойти быстро и грязно и позвонить .Result на Task (не делайте этого! За исключением случаев, когда вы ждете сначала, как в answer Лиама), или просто инициализируйте новый список и добавьте элементы в цикле foreach:

var additionalInformation = new List<AdditionalInformationItem>();
foreach (var x in response.AdditionalInformation)
{
    var item = new AdditionalInformationItem
        {
            StatementCode = x?.StatementCode?.Value,
            LimitDateTime = x?.LimitDateTime?.Item?.Value,
            StatementTypeCode = x?.StatementTypeCode?.Value,
            StatementDescription = x?.StatementDescription?.Value,
            AdditionalInformationResult = await BuildAdditionalInformationPointers(x)
        };

    additionalInformation.Add(item);
}
...