Assuming I have an async builder method and I need to convert a collection of db models into a collection of UI models, I wrote the code below (simplified for example).
After reading this medium article, the code was refactoring to bubble ASYNC all the way up but I'd still like to know
- will
collection.GetConsumingEnumerable()
block, leading to deadlocks, similar to.Wait
or.Result
- what is the preferred way to stream items in an async method
public IEnumerable<GenericDevice> GetGenericDevices(SearchRequestModel srModel)
{
var collection = new BlockingCollection<GenericDevice>(new ConcurrentBag<GenericDevice>());
Task.Run(() => QueueGenericDevices(collection, srModel));
foreach (var genericDevice in collection.GetConsumingEnumerable())
{
yield return genericDevice;
}
}
private async Task QueueGenericDevices(BlockingCollection<GenericDevice> collection, SearchRequestModel srModel)
{
var efDevices = _dbDeviceRepo.GetEfDevices(srModel);
var tasks = efDevices
.Select(async efDevice =>
{
var genericDevice = await BuildGenericDevice(efDevice, srModel);
collection.Add(genericDevice);
});
await Task.WhenAll(tasks);
collection.CompleteAdding();
}