Problem: method doesn't finish executing (no exception, http request in pending
status).
I have to implement next interface:
public interface IQueryableUserStore<TUser, in TKey> : IUserStore<TUser, TKey>, IDisposable where TUser : class, IUser<TKey>
{
IQueryable<TUser> Users { get; }
}
I did it like this:
public IQueryable<User> Users {
get { return (this._userRepository.GetAll().Result).AsQueryable(); }
}
Here is GetAll()
implementation:
public async Task<IEnumerable<User>> GetAll() {
const string query = @"
select * from [dbo].[User]
";
return (await this._db.QueryAsync<User>(query, new {}));
}
Edit: I remove async behavior from method and method call and it works. But why shouldn't it works with async?
This works:
public IQueryable<User> GetAll() {
const string query = @"
select * from [dbo].[User]
";
return this._db.Query<User>(query, new {}).AsQueryable();
}
Task.Result
can easily cause deadlocks, as I explain on my blog.
You need to decide if you want your database access to be synchronous or asynchronous. If synchronous, then go synchronous all the way:
public IQueryable<User> GetAll() {
const string query = @"
select * from [dbo].[User]
";
return this._db.Query<User>(query, new {}).AsQueryable();
}
If asynchronous, then go asynchronous all the way:
public interface IQueryableUserStore<TUser, in TKey> : IUserStore<TUser, TKey>, IDisposable where TUser : class, IUser<TKey>
{
Task<IQueryable<TUser>> GetUsers();
}
Sync-over-async is an antipattern in the vast majority of cases. I talk more about the principle of async all the way in an MSDN article.