0

I am trying to convert a synchronous method with GetAwaiter()GetResult() to an asynchronous method. I have the following code:

private List<MyObject> GetPairsToHandle(SpecificationBuilder specificationBuilder)
{
    using (var context = _contextFactory.Create())
    {
        var toHandleFromDb = GetItemsToHandle().ToList();
        var leadsSet = new Dictionary<int, ProcessingLead>();            
        var toHandle = toHandleFromDb
            .Select(o =>
            {
                ProcessingLead lead = null;
                if (o.Item1 != null)
                {
                    if (leadsSet.ContainsKey(o.Item1.ID))
                        lead = leadsSet[o.Item1.ID];
                    else
                    {
                        lead = _entityMapper.Map(o.Item1);
                        leadsSet.Add(o.Item1.ID, lead);
                    }
                }
                ProcessingLeadConsumer consumer = null;
                if (o.Item2 != null)
                {
                    if (lead == null)
                    {
                        consumer = new ProcessingLeadConsumer
                        {
                            Id = o.Item2.Id,
                            CompanyGuid = o.Item2.CompanyGuid
                        };
                    }
                    else
                    {
                        consumer = _companyServiceFactory.Create(lead.Country, lead.Brand).GetCompanyAsync(o.Item2.CompanyGuid).GetAwaiter().GetResult();
                    }
                }
                return new MyObject(lead, consumer);
            })
            .ToList();
    
        return toHandle;
    }
}
    

Instead of .GetAwaiter().GetResult() I would want it to run asynchronously. So I changed it to the following:

var toHandle = toHandleFromDb
.Select(async o => 
{
    ProcessingLead lead = null;
    if (o.Item1 != null)
    {
        if (leadsSet.ContainsKey(o.Item1.ID))
            lead = leadsSet[o.Item1.ID];
        else
        {
            lead = _entityMapper.Map(o.Item1);
            leadsSet.Add(o.Item1.ID, lead);
        }
    }
    ProcessingLeadConsumer consumer = null;
    if (o.Item2 != null)
    {
        if (lead == null)
        {
            consumer = new ProcessingLeadConsumer
            {
                Id = o.Item2.Id,
                CompanyGuid = o.Item2.CompanyGuid
            };
        }
        else
        {
            consumer = await _companyServiceFactory.Create(lead.Country, lead.Brand).GetCompanyAsync(o.Item2.CompanyGuid);
        }
    }
    return new MyObject(lead, consumer);
})
.ToList();
    

Now I have to questions:

  1. How do I convert List<System.Threading.Tasks.Task.. to <List<MyObject
  2. Is it safe to call an async lamda from a synchronous method? I cannot convert this method to async. What would be the best solution?
Adi Lavi
  • 9
  • 4
  • 1
    Does this answer your question? [Await for list of Tasks](https://stackoverflow.com/questions/17621632/await-for-list-of-tasks) – pinkfloydx33 Jul 25 '20 at 16:25
  • cannot `await Task.WhenAll(toHandle)` since my method is not `async` – Adi Lavi Jul 25 '20 at 16:25
  • Sorry I missed that you weren't also converting the outer method. In that case the duplicate still applies. Use `Task.WaitAll(toHandle);` followed by `toHandle.Select(c => c.Result).ToList()` which is safe to do once all tasks are complete though you should convert the outer method as well if at all possible – pinkfloydx33 Jul 25 '20 at 16:27
  • Cannot convert `System.Collections.Generic.IEnumerable – Adi Lavi Jul 25 '20 at 16:32
  • 1
    I knew that what going to be your next comment and as I awaited its inevitable posting, I've been debating about whether I was going to respond or give a lecture on figuring things out yourself. Its not that hard to read an error message and consult official doc.. Don't rely on other people to read them for you, you'll be doing yourself a favor. I think I've made my point. `Task.WaitAll` needs an array, so `Task.WaitAll(toHandle.ToArray())` – pinkfloydx33 Jul 25 '20 at 16:37
  • Does this answer your question? [How to call asynchronous method from synchronous method in C#?](https://stackoverflow.com/questions/9343594/how-to-call-asynchronous-method-from-synchronous-method-in-c) – devNull Jul 25 '20 at 16:41
  • Task.WaitAll is better option .otherwise in syn call can use like consumer = Task.Run(async () => await_companyServiceFactory.Create(lead.Country, lead.Brand).GetCompanyAsync(o.Item2.CompanyGuid)).GetAwaiter().GetResult(); – LDS Jul 25 '20 at 18:43

0 Answers0