6

I am trying to fill in the Dictionary<long, Data> . Method GetData which returns data is async so I use following code to get the dictionary:

var myDictionary = entities
  .GroupBy(e => e.EntityId)
  .Select(e => e.First())
  .ToDictionary(e => e.EntityId, async entity => await GetData(entity));

Unfortunately myDictionary is of type Dictionary<long, Task<Data>>

How to fill in the using async lambda in ToDictionary?

michal.jakubeczy
  • 8,221
  • 1
  • 59
  • 63
  • The simplest, but arguably incorrect workaround is to use `GetData(entity).GetAwaiter().Result`, as this simply forces all the asynchronous operations to execute synchronously. But there is no support in either LINQ or PLINQ (that I know of) for properly constructing collections asynchronously. – Jeroen Mostert Apr 13 '18 at 14:10
  • @JeroenMostert: yeah, but I lose all the benefits of async/await – michal.jakubeczy Apr 13 '18 at 14:14
  • You need `.ToDictionaryAsync`, but such a method does not exist (except in EF, but then it's never a fully generic version). [Duplicate](https://stackoverflow.com/q/37796139/4137916), albeit with no really good answers. – Jeroen Mostert Apr 13 '18 at 14:22

1 Answers1

4

Try this:

var myDictionary = 
                (await Task.WhenAll(entities
                .GroupBy(e => e.EntityId)
                .Select(e => e.First())
                .Select(async e => new {e.EntityId, Data = await GetData(e)})))
                  .ToDictionary(e => e.EntityId, e => e.Data);
Magnus
  • 45,362
  • 8
  • 80
  • 118