Is there any difference between using async methods provided by System.Data.Entity from Entity Framework and wrapping the same non asynchronous methods with a Task.FromResult ?
For example :
private Task<int> GetCountAsync()
{
return this._myDbContext.Set<MyEntity>().CountAsync();
}
and
private Task<int> GetCountAsync()
{
return Task.FromResult(this._myDbContext.Set<MyEntity>().Count());
}
Yes it could, because if the ADO driver implements async methods using the IOCP thread pool (and it does), will not use a worker thread to wait on the operation, instead will use a special waiting mechanism using I/O Completion Ports, in that way, the server should be able to best scale when there's a lot of contention that do long-running operation against IO like a database query does.
Check some article you can find googling:
Asynchronous Command Execution in ADO.NET 2.0
Took from the last link:
In previous versions of the .NET Framework it was possible to simulate non-blocking execution by using asynchronous delegates or the ThreadPool class; however, those solutions simply blocked another thread in the background, making them far from ideal for cases where it is important to avoid blocking threads...
ADO.NET/SqlClient asynchronous command execution support is based on true asynchronous network I/O under the covers (or non-blocking signaling in the case of shared memory).
...there are no blocked background threads waiting for a particular I/O operation to finish, and we use the overlapped I/O and the input/output completion ports facilities of the Windows 2000/XP/2003 operating systems to make it possible to use a single thread (or a few of them) to handle all the outstanding requests for a given process.
Edit: Move from comment to here to extend the answer regarding the specific problem of Async Repository Pattern:
I think you should expose those Async methods you need, extending the generic repository, avoiding to couple on EF and avoiding task wrapping, adding CountAsync, AddSync, FindAsync, and all sort of methods you need also async.
Example of repository:
public interface IRepository<T> where T : class
{
Task<int> AddAsync(T t);
Task<int> RemoveAsync(T t);
Task<List<T>> GetAllAsync();
Task<int> UpdateAsync(T t);
Task<int> CountAsync();
Task<T> FindAsync(Expression<Func<T, bool>> match);
Task<List<T>> FindAllAsync(Expression<Func<T, bool>> match);
}
CountAsync implementation:
public async Task<int> CountAsync()
{
return await _dbContext.Set<T>().CountAsync();
}
Directly took from the post to leave here all the contents.
Then you can extend also your generic repository.
Edit: added some useful readings: