-1

A portion of my code involving an async Lambda function is failing. Here is the snippet:

var uniqueNotes = (await _api.GetContactAssocData(contactId))?
    .Results?
    .Select(async r =>
    {
        var noteDetail = await _api.GetNoteDetails(r.ToObjectId);
        return $"{noteDetail?.Properties?.Timestamp}|{noteDetail?.Properties?.NoteBody}";
    }).ToHashSet();

I have anonymized the method/variable names to protect my employer's IP.

The error given by the compiler is Cannot implicitly convert type 'System.Collections.Generic.HashSet<System.Threading.Tasks.Task<string>>' to 'System.Generics.HashSet<string>'

This error message would make total sense if I were failing to await the Task inside the statement block. But as you can see, I appear to have everything correctly in place for my statement to return: there is an async at the start of the Lambda, and the method call inside my block is awaited before assigning its properties to the string that is returned by the block.

Thus, it seems this block would return an IEnumerable of strings rather than of Task<string>s, since each Task generated by the Select() is (theoretically) being awaited before being evaluated.

Do you have any idea what I might be doing wrong?

QBBryant
  • 161
  • 1
  • 11

2 Answers2

0

Select tasks then handle the results when completed

var noteDetailsTasks = (await _api.GetContactAssocData(contactId))?
    .Results?
    .Select(r => _api.GetNoteDetails(r.ToObjectId));

var uniqueNotes = (await Task.WhenAll(noteDetailsTasks))
    .Select(noteDetail => 
        $"{noteDetail?.Properties?.Timestamp}|{noteDetail?.Properties?.NoteBody}")
    .ToHashSet();
Moho
  • 15,457
  • 1
  • 30
  • 31
  • Thanks - this is an elegant solution. I'm tempted to test the performance of your solution (both in terms of time and space) vs. the ForEach()-based solution provided by @svyatoslav-danyliv . Would you happen to know which would perform better? – QBBryant Jun 30 '22 at 21:48
  • 1
    Looping with awaiting each call to `_api.GetNoteDetails(...)` requires each call to execute sequentially, so execution time would be approximately the sum of all individual executions. This solution allows each call to execute concurrently, which should mean the approximate execution time would be the length of time of the longest running call to `_api.GetNoteDetails(...)`. For a simplified example, if each call takes 1 second and there are 10 executions requried, this solution should take approximately 1 second to complete while the looping w/ awaits solution would take approximately 10s – Moho Jun 30 '22 at 22:03
-1

You cannot use async in Select, do awaits in foreach and append items to HashSet manually.

This comment posted by @svyatoslav-danyliv answered my question:

QBBryant
  • 161
  • 1
  • 11