Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async Await in Lambda expression where clause

I would want to call an async method inside lambda expression. Please help me doing the below

eg -

return xyz.Where(async x=> await AsyncMethodCall(x.val));

And the Async method looks like

public async Task<bool> AsyncMethodCall(Data d){...}

When I do the above, I get the following error

Error CS4010 Cannot convert async lambda expression to delegate type 'Func<Data, bool>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<Data, bool>'.

Thanks in advance for the help

like image 386
Sandy Avatar asked May 11 '17 13:05

Sandy


1 Answers

Asynchronous sequences are tricky because you really have to think about what specifically you want the code to do.

For example, you could want to execute the AsyncMethodCall calls sequentially, and then return all the results:

var result = new List<T>();
foreach (var d in xyz)
  if (await AsyncMethodCall(d.val))
    result.Add(d);
return result;

Or, you could execute all the AsyncMethodCall calls concurrently, and then collect and return the results (again, all at once):

var tasks = xyz.Select(async d => new { d, filter = await AsyncMethodCall(d.val) });
var results = await Task.WhenAll(tasks);
return results.Where(x => x.filter).Select(x => x.d);

Or, you could execute all the AsyncMethodCall calls sequentially, and produce the results one at a time. This approach is incompatible with IEnumerable<T> (assuming you want to keep the call asynchronous). If you want to produce a sequence where AsyncMethodCall is asynchronously invoked during sequence enumeration, then you would need to change to IAsyncEnumerable<T>. If you want to produce a sequence that is started by the consumer and then produces results on its own, you would need to change to IObservable<T>.

Or, you could execute all the AsyncMethodCall calls concurrently, and produce the results one at a time. This is also incompatible with IEnumerable<T>; you would need to change to IObservable<T>. And you would also need to decide whether to maintain the original ordering, or to produce them in order of AsyncMethodCall completing.

like image 114
Stephen Cleary Avatar answered Sep 17 '22 11:09

Stephen Cleary