Search code examples
async-awaitado.netgrpcdappercancellation

Dapper: How to cancel an async non-buffered query?


Using Dapper's SqlMapper.QueryAsync<T> method for a mix of buffered (small, predetermined in size) and non-buffered (large, potentially millions of rows in size, unable to tell in advance) queries in a gRPC API.

Testing the scenario when the API client dies/disconnects, the non-buffered query stays alive on the DB until it is fully executed even though the results are no longer being consumed by the calling service, which is wasting valuable DB resources.
Looking into the QueryAsync code, the cancellation token (which is correctly populated on API client death/disconnect) is only taken into consideration in the buffered case.

How do I make sure that the non-buffered query on the DB is correctly cancelled?


Solution

  • The non-buffered async API is currently... not fully async, because: IAsyncEnumerable<T> did not exist at the time. This will be revisited in v3, as an API break - along with async cancellation generally. So short answer: right now, you can't.