Is this a reasonable way to add async functionality to the IDbCommand interface?
public async static Task<IDataReader> ExecuteReaderAsync(this IDbCommand self) {
DbCommand dbCommand = self as DbCommand;
if (dbCommand != null) {
return await dbCommand.ExecuteReaderAsync().ContinueWith(task => (IDataReader)task.Result);
} else {
return await Task.Run(() => self.ExecuteReader());
}
}
Specifically, I'm not entirely sure what the effects of using "ContinueWith" to fake the covariance of "Task".
Also, in the unlikely case that the incoming "self" instance does not inherit from DbCommand, will a thread pool thread be consumed and blocked during the execution of "self.ExecuteReader()"?
Here's a link to my complete implementation of IDb extensions for async support.
Thank you
Just because it is cleaner, I would take advantage of the fact that you’re using
async
andawait
to do away with the cast in theContinueWith()
.await
evaluates to an object of typeTResult
when used on aTask<TResult>
. I was going to suggest the syntaxreturn (IDataReader)await dbCommand.ExecuteReaderAsync();
, but then I remembered that the compiler already knows thatDbDataReader
isIDataReader
. Tested in VS 2013 and VS 2015 Preview (not sure what you’re targeting, but I assume all C# compilers that supportawait
should work with this):Now you’re using
await
to its fuller potential and saving a few bytes of code ;-).The biggest concern with this implementation is, of course, the runtime type testing in
self as DbCommand
. In my opinion,DbCommand
should be used instead ofIDbCommand
. This would let you remove the runtime cast. However, you probably wouldn’t have written this library if there was no problem with switching everything fromIDbCommand
toDbCommand
and the runtime type check is probably performant enough.Visual Studio 2017 Syntax
With newer versions of C#, you can use the
is
keyword instead ofas
to write more concise code: