I have a gRPC client and I want to have a method that simplifies its use. The method should return IAsyncEnumerable
of items being streamed from the gRPC server.
I have a specified timeout for the streaming not to exceed. If the timeout occurs, I want to just walk away with all the items I managed to fetch so far.
Here's what I tried to do:
public async IAsyncEnumerable<Item> Search(
SearchParameters parameters,
CancellationToken cancellationToken,
IDictionary<string, string> headers = null)
{
try
{
await _client.Search(
MapInput(parameters),
cancellationToken: cancellationToken,
deadline: DateTime.UtcNow.Add(_configuration.Timeout),
headers: MapHeaders(headers))
.ResponseStream.ForEachAsync(item =>
{
yield return MapSingleItem(item); // compilation error
});
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded)
{
_logger.LogWarning("Steam finished due to timeout, a limited number of items has been returned");
}
}
Logically, that should work. However, the yield
keyword is not supported within lambdas, so it does not compile. Is there any other way I could write it?