C#webapi异步上下文问题

时间:2017-04-08 21:54:51

标签: c# entity-framework asynchronous asp.net-web-api

我有两个控制台应用程序同时调用我的webapi,然后我在控制台应用程序中回复了我的api的响应:

  

在上一次异步操作完成之前,在此上下文中启动了第二个操作。使用'await'确保在此上下文上调用另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。

所以他们同时调用我的webapi,然后webapi中的某些内容无法处理这两个异步调用,因此会返回此错误。

我检查了webapi项目中的所有代码,并且所有方法都是异步的并等待,所以我看不出为什么会得到这个。

这是webapi的代码。

控制器:

public class FederationsController : ApiController
{
    private readonly IFederationRepository _federationRepository;

    public FederationsController(IFederationRepository federationRepository)
    {
        _federationRepository = federationRepository;
    }

    [HttpGet]
    [Route("federations", Name = "GetFederations")]
    public async Task<IHttpActionResult> GetFederations()
    {
        var federations = await _federationRepository.GetAllAsync();
        return Ok(federations.ToModel());
    }
}

存储库

 public class FederationRepository : IFederationRepository, IDisposable
{
    private Models.DataAccessLayer.CompetitionContext _db = new CompetitionContext();

    #region IQueryable
    private IQueryable<Models.Entities.Federation> FederationWithEntities()
    {
        return _db.Federations.Include(x => x.Clubs)
                              .Where(x => !x.DeletedAt.HasValue && x.Clubs.Any(y => !y.DeletedAt.HasValue));
    }
    #endregion IQueryable

public async Task<IEnumerable<Models.Entities.Federation>> GetAllAsync()
    {
        return await FederationWithEntities().ToListAsync();
    }
}

映射

public static class FederationMapper
{
    public static List<Federation> ToModel(this IEnumerable<Models.Entities.Federation> federations)
    {
        if (federations == null) return new List<Federation>();
        return federations.Select(federation => federation.ToModel()).ToList();
    }

    public static Federation ToModel(this Models.Entities.Federation federation)
    {
        return new Federation()
        {
            Name = federation.Name,
            FederationCode = federation.FederationCode,
            CreatedAt = federation.CreatedAt,
            UpdatedAt = federation.UpdatedAt
        };
    }
}

的DbContext

public class CompetitionContext : DbContext
{
    public CompetitionContext() : base("ContextName")
    {
    }

    public DbSet<Federation> Federations { get; set; }
}

UnityConfig

 public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();
        container.RegisterType<IFederationRepository, FederationRepository>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}

感谢您提供所有建议/帮助。

1 个答案:

答案 0 :(得分:0)

在您的存储库中,您将创建一个CompetitionContext并重用它。我假设IoC设置将存储库注册为某种单一实例,因此每次都使用相同的存储库。如果是这种情况,您应该为每个方法调用创建一个新的CompetitionContext。

此外,可能应该确保使用using语句关闭它。

我也不清楚您的代码片段为什么要从该FederationWithEntities返回IQueryable,方法,您还有其他使用它的东西吗?

无论如何,我可能会改变GetAllMethod是这样的:

public async Task<IEnumerable<Models.Entities.Federation>> GetAllAsync()
{
  using (Models.DataAccessLayer.CompetitionContext _db = new CompetitionContext())
  {
     return _db.Federations.Include(x => x.Clubs)
                           .Where(x => !x.DeletedAt.HasValue && x.Clubs.Any(y => !y.DeletedAt.HasValue))
                           .ToListAsync();
  }
}