Getter property with async method doesn't finish executing

.net asp.net asp.net-identity c# dapper

Question

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();
}

Popular Answer

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.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why