Почему некоторые методы, возвращающие задачу, не помечены как асинхронные в шаблоне общего хранилища - PullRequest
0 голосов
/ 08 ноября 2019

Я читал действительно классную статью о создании универсального репозитория Async, используя следующую ссылку https://blog.zhaytam.com/2019/03/14/generic-repository-pattern-csharp/ Интерфейс определяет все операции как задачи, но реализация предпочитает не использовать шаблон асинхронизации / ожидания в нескольких методах. Я хотел бы углубить мое понимание этого, поэтому решил опубликовать здесь. На первый взгляд может показаться, что клиент может не знать, что ему нужно ждать методов, которые не помечены как асинхронные, но я, вероятно, не правильно понимаю это. Кто-нибудь может прокомментировать, почему автор решил не использовать асинхронность для некоторых методов, которые возвращают задачу, а не для других?

public interface IAsyncRepository<T> where T : BaseEntity
{

    Task<T> GetById(int id);
    Task<T> FirstOrDefault(Expression<Func<T, bool>> predicate);

    Task Add(T entity);
    Task Update(T entity);
    Task Remove(T entity);

    Task<IEnumerable<T>> GetAll();
    Task<IEnumerable<T>> GetWhere(Expression<Func<T, bool>> predicate);

    Task<int> CountAll();
    Task<int> CountWhere(Expression<Func<T, bool>> predicate);

}

public class EfRepository<T> : IAsyncRepository<T> where T : BaseEntity
{

    #region Fields

    protected DataDbContext Context;

    #endregion

    public EfRepository(DataDbContext context)
    {
        Context = context;
    }

    #region Public Methods

    public Task<T> GetById(int id) => Context.Set<T>().FindAsync(id);

    public Task<T> FirstOrDefault(Expression<Func<T, bool>> predicate)
        => Context.Set<T>().FirstOrDefaultAsync(predicate);

    public async Task Add(T entity)
    {
        // await Context.AddAsync(entity);
        await Context.Set<T>().AddAsync(entity);
        await Context.SaveChangesAsync();
    }

    public Task Update(T entity)
    {
        // In case AsNoTracking is used
        Context.Entry(entity).State = EntityState.Modified;
        return Context.SaveChangesAsync();
    }

    public Task Remove(T entity)
    {
        Context.Set<T>().Remove(entity);
        return Context.SaveChangesAsync();
    }

    public async Task<IEnumerable<T>> GetAll()
    {
        return await Context.Set<T>().ToListAsync();
    }

    public async Task<IEnumerable<T>> GetWhere(Expression<Func<T, bool>> predicate)
    {
        return await Context.Set<T>().Where(predicate).ToListAsync();
    }

    public Task<int> CountAll() => Context.Set<T>().CountAsync();

    public Task<int> CountWhere(Expression<Func<T, bool>> predicate) 
        => Context.Set<T>().CountAsync(predicate);

    #endregion

}

Ответы [ 3 ]

1 голос
/ 09 ноября 2019

Я подозреваю, что это было случайное упущение.

Мне трудно увидеть какую-либо выгоду в ожидании некоторых методов базового класса, а не других.

1 голос
/ 08 ноября 2019

Обратите внимание, что методы имеют async и await. В тех методах, которые вы ожидаете, чтобы выполнить, чтобы получить результат, в то время как в тех методах без await вам все равно, когда они будут выполнены

0 голосов
/ 11 ноября 2019

Используя ТОЛЬКО представленный код, за исключением метода public async Task Add(T entity), использование "async / await" кажется совершенно случайным.

Во всех случаях вы можете либо преобразовать метод в async и поставить await непосредственно перед возвратом, ИЛИ вы можете удалить async и awaits и вернуть Task.

В итоге результат одинаков как в отношении скомпилированного кода, так и в отношении поведения во время выполнения (в основном производительность)

...