Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Data.IDbCommand and asynchronous execution?

System.Data.SqlClient.SqlCommand has methods

BeginExecuteNonQuery
BeginExecuteReader
BeginExecuteXmlReader

and

EndExecuteNonQuery
EndExecuteReader
EndExecuteXmlReader

for asynchronous execution.

System.Data.IDbCommand only has

ExecuteNonQuery
ExecuteReader
ExecuteXmlReader

which are for synchronous operations only.

Is there any interface for asynchronous operations ?
In addition, why is there no BeginExecuteScalar ?

like image 391
Stefan Steiger Avatar asked Feb 02 '12 11:02

Stefan Steiger


People also ask

Should my database calls be asynchronous?

Asynchronous calls are most useful when facing relatively infrequent large, expensive operations that could tie up response threads which could otherwise be servicing requests while the originator waits. For quick, common operations, async can slow things down.

Is ExecuteNonQuery asynchronous?

ExecuteNonQueryAsync(CancellationToken)This is the asynchronous version of ExecuteNonQuery(). Providers should override with an appropriate implementation. The cancellation token may optionally be ignored.

How to use Async await in ADO net?

When calling an async method, a task is returned. When the await operator is applied to a task, the current method exits immediately. When the task finishes, execution resumes in the same method. Asynchronous calls are not supported if an application also uses the Context Connection connection string keyword.

What is async await in C#?

An async keyword is a method that performs asynchronous tasks such as fetching data from a database, reading a file, etc, they can be marked as “async”. Whereas await keyword making “await” to a statement means suspending the execution of the async method it is residing in until the asynchronous task completes.


2 Answers

I recommend to treat DbCommand and its friends as if they were interfaces when consuming database APIs. For the sake of generalizing an API over various database providers, DbCommand achieves just as well as IDbCommand—or, arguably, better, because it includes newer technologies such as proper awaitable Task *Async() members.

MS can’t add any new methods with new functionality to IDbCommand. If they were to add a method to IDbCommand, it is a breaking change because anyone is free to implement that interface in their code and MS has put much effort into preserving ABI and API compatibility in the framework. If they expanded interfaces in a release of .net, customer code which previously worked would stop compiling and existing assemblies which are not recompiled would start encountering runtime errors. Additionally, they can’t add proper *Async() or Begin*() methods via extension methods without doing ugly casting to DbCommand behind the scenes (which is a bad practice itself, breaking type safety and unnecessarily introducing dynamic runtime casting).

On the other hand, MS can add new virtual methods to DbCommand without breaking ABI. Adding new methods to a base class might be considered breaking the API (compile-time, not as bad to break as runtime) because if you inherited DbCommand and had added a member with the same name, you’ll start getting the warning CS0108: 'member1' hides inherited member 'member2'. Use the new keyword if hiding was intended.). Thus, DbCommand can get the new features with minimal impact on consuming code which follows good practices (e.g., most stuff will keep working as long as it doesn’t work against the type system and call methods using something like myCommand.GetType().GetMethods()[3].Invoke(myCommand, …)).

A possible strategy which MS could have used to support people who like interfaces would have been to introduce new interfaces with names like IAsyncDbCommand and have DbCommand implement them. They haven’t done this. I don’t know why, but they probably didn’t do this because it would increase complication and the alternative of directly consuming DbCommand provides most of the benefits to consuming interfaces with few downsides. I.e., it would be work with little return.

like image 167
binki Avatar answered Oct 01 '22 03:10

binki


IDbCommand does not have the begin/end async methods because they did not yet exist in the original .NET 1.1 release of ADO.NET, and when the async methods were added in .NET 2.0 it would have been a breaking change to add those to IDbCommand (adding members to an interface is a breaking change for implementors of that interface).

I don't know why BeginExecuteScalar doesn't exist, but it can be implemented as an extension method that wraps around BeginExecuteReader. Anyway in .NET 4.5 we now have ExecuteScalarAsync which is easier to use.

like image 30
Jared Moore Avatar answered Oct 01 '22 02:10

Jared Moore