IDbCommand missing ExecuteReaderAsync

I am using .NET Core 2.0. I have the following function that calls IDbCommand.ExecuteReader

 public async Task<IEnumerable<Widget>> ReadAllAsync( System.Data.IDbConnection databaseConnection, System.Data.IDbTransaction databaseTransaction) { var commandText = "SELECT WidgetId, Name FROM Widget"; // _databaseCommandFactory.Create returns an IDbCommand var command = this._databaseCommandFactory.Create(databaseConnection, databaseTransaction, commandText); using (var dataReader = command.ExecuteReader()) { // iterate through the data reader converting a collection of Widgets (`IEnumerable<Widget>`) } } 

I get a warning

In this asynchronous method, there are no β€œwait” statements and will be executed synchronously. Think about how to use the β€œwait” operator to wait for non-blocking API calls or β€œwait for Task.Run (...)” to do the work of binding to the processor in the background thread.

I was thinking about converting the command.ExecuteReader() operator to await Task.Run(() => command.ExecuteReader()) as indicated in the warning. But I'm not sure if this is the right approach, I believe that Task.Run(...) designed to work on a CPU basis. This is primarily work with IO.

So my questions

  • Is Task.Run(...) right approach?
  • If not, is there another solution?
  • Or should I just ignore this warning and wait until ExecuteReaderAsync is added to the IDbCommand interface? (is there a plan for this?)
+5
source share
1 answer

The await is what allows a method to run asynchronously. The async allows you to use the await keyword in this method and helps with return control.

Until await , the method will execute synchronously.

So, all this is done synchronously. It will not return anything or move the method until it is complete.

 public async Task<IEnumerable<Widget>> ReadAllAsync( System.Data.IDbConnection databaseConnection, System.Data.IDbTransaction databaseTransaction) { var commandText = "SELECT WidgetId, Name FROM Widget"; // _databaseCommandFactory.Create returns an IDbCommand var command = this._databaseCommandFactory.Create(databaseConnection, databaseTransaction, commandText); using (var dataReader = command.ExecuteReader()) { // iterate through the data reader converting a collection of Widgets (`IEnumerable<Widget>`) } } 

Dropping on DbCommand , which are already being executed in most of the IDbCommand implementations, then casting will be performed on DbCommand and adding the wait, for example.

 var dbCommand = (DbCommand) command; using (var dataReader = await dbCommand.ExecuteReaderAsync()) { while (await dataReader.ReadAsync()) { // iterate through the data reader converting a collection of Widgets (`IEnumerable<Widget>`) } } 

or create a separate task

 public async Task MyAsyncMethod() { // Do your stuff that takes a long time } public async Task CallMyAsyncMethod() { // We can await Tasks, regardless of where they come from. await MyAsyncMethod(); } 

This way - the program will continue, waiting for a return from this method, instead of blocking the user interface and everything else.

+6
source

Source: https://habr.com/ru/post/1271145/


All Articles