如何在第一次使用生活方式 PerWebRequest 完成上下文和异步调用之前在我的上下文上等待第二次操作

how wait second operation on my context before first completes with lifestyle PerWebRequest for the context and asynchronous calls to it

我的通用存储库接口是:

public interface IGenericRepository<T , TEntityKey> where T : EntityBase<TEntityKey>
{
    IEnumerable<T> GetAll();
    IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate);
    T FindBy(TEntityKey entityKey);
    Task<T> FindByAsync(TEntityKey entityKey);
    T Add(T entity);
    T Delete(T entity);
    void Edit(T entity);
    void Save();
    void Dispose();
}

我在实现我的存储库时对所有异步方法使用了 await。 使用 Castle Windsor 作为 IOC 容器,我使用 PerWebRequestLifeStyle.

安装了我的上下文

客户端发送两个请求,每个请求映射到 IGenericRepository 实现的不同存储库,出现此异常:

A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

我将上下文的生活方式更改为瞬态,但异常仍然出现。 谁能帮助我哪里错了?

GenericRepository 实施:

 public abstract class GenericRepository<T, TEntityKey> : IGenericRepository<T, TEntityKey>
    where T : EntityBase<TEntityKey>
{
    protected IDbContext _entities;
    protected readonly IDbSet<T> _dbset;

    protected GenericRepository(IDbContext context)
    {
        _entities = context;
        _dbset = _entities.Set<T>();
    }

    ~GenericRepository()
    {
        _entities.Dispose();
    }

    public virtual IEnumerable<T> GetAll()
    {
        return _dbset.AsEnumerable<T>();
    }

    public IEnumerable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {

        IEnumerable<T> query = _dbset.Where(predicate).AsEnumerable();
        return query;
    }

    public T FindBy(TEntityKey entityKey)
    {
        var result = _dbset.SingleOrDefault(e => e.Id.ToString() == entityKey.ToString());
        return result;
    }

    public Task<T> FindByAsync(TEntityKey entityKey)
    {
        var result = _dbset.SingleOrDefaultAsync(e => e.Id.ToString() == entityKey.ToString());
        return result;
    }

    public virtual T Add(T entity)
    {
        return _dbset.Add(entity);
    }

    public virtual T Delete(T entity)
    {
        return _dbset.Remove(entity);
    }

    public virtual void Edit(T entity)
    {
        _entities.Entry(entity).State = EntityState.Modified;
    }

    public virtual void Save()
    {
        _entities.SaveChanges();
    }

    public async Task SaveAsync()
    {
        await _entities.SaveChangesAsync();
    }

    public void Dispose()
    {
        if (_entities != null)
        {
            _entities.Dispose();
            _entities = null;
            GC.SuppressFinalize(this);
        }
    }
}

我认为您有一些像这样的继承存储库:

Public Repository1<Class1, KeyClass1> : GenericRepository<T, TEntityKey>
{
    Public Repository1(IDbContext c) : base(c) { }
}

Public Repository2<Class2, KeyClass2> : GenericRepository<T, TEntityKey>
{
    Public Repository2(IDbContext c) : base(c) { }
}

这意味着您的 Castle Windsor 将为 IDbContext 创建一个实例并将其注入到导致错误的两个存储库中。

我可以建议您将基础 class 更改为:

public abstract class GenericRepository<T, TEntityKey> : IGenericRepository<T, TEntityKey>
    where T : EntityBase<TEntityKey>
{
    protected IDbContext _entities;
    protected readonly IDbSet<T> _dbset;

    protected GenericRepository()
    {
        _entities = new MyDbContext();
        _dbset = _entities.Set<T>();
    }

    ...
}