I am creating a .NET 4.0 application that uses ADO.NET, so I cannot use async / wait. I don't want a solution for this, but I really want to know which of the following implementations is best and why. My unit tests pass for all three implementations, but I want to know the difference between the three.
# 1 Attachment Tasks
In my first implementation, I transfer the task to another task. I think deploying two tasks is bad for performance, but I'm not sure.
public virtual Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken) { return Task.Factory.StartNew(() => { var sqlCommand = CheckIfSqlCommand(dbCommand); PrepareExecuteReader(dbCommand); return Task<IDataReader> .Factory .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null) .Result; }, cancellationToken); }
# 2 Using TaskCompletionSource
Then I tried to wrap the result in a TaskCompletionSource , so I only have one task.
public virtual Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken) { var taskCompletionSource = new TaskCompletionSource<IDataReader>(); var sqlCommand = CheckIfSqlCommand(dbCommand); PrepareExecuteReader(dbCommand); var reader = Task<IDataReader> .Factory .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null) .Result; taskCompletionSource.SetResult(reader); return taskCompletionSource.Task; }
# 3 return directly to the task
My final solution is to directly return the created task instead of packing it.
public virtual Task<IDataReader> ExecuteReaderAsync(IDbCommand dbCommand, CancellationToken cancellationToken) { var sqlCommand = CheckIfSqlCommand(dbCommand); PrepareExecuteReader(dbCommand); return Task<IDataReader> .Factory .FromAsync(sqlCommand.BeginExecuteReader, sqlCommand.EndExecuteReader, null); }
So basically my question is:
Which option to use or is there a better way to do this?
annemartijn Feb 27 '14 at 9:05 2014-02-27 09:05
source share