【发布时间】:2017-09-04 04:10:48
【问题描述】:
我有两个控制台应用程序同时调用我的 webapi,我在控制台应用程序中返回来自我的 api 的以下响应:
在前一个异步操作完成之前,在此上下文上启动了第二个操作。使用 'await' 确保在此上下文上调用另一个方法之前已完成任何异步操作。不保证任何实例成员都是线程安全的。
所以他们同时调用了我的 webapi,然后 webapi 内部的东西无法处理这 2 个异步调用,所以返回了这个错误。
我检查了 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);
}
}
感谢您的所有建议/帮助。
【问题讨论】:
-
我会检查是否有什么东西导致你的统一注册被搞砸了,它就像一个单一的 IFederationRepository 在请求之间共享。尝试在统一注册中显式设置
TransientLifetimeManger,看看它是否有任何改变。 -
@ScottChamberlain 我试过这个容器。RegisterType
(new HierarchicalLifetimeManager());但如果这就是你的意思,那也没有解决问题? -
HierarchicalLifetimeManager是绝对错误的管理器,每次解析都需要一个新的类副本。你需要一个TransientLifetimeManger -
缺少一些东西,只有在同时执行两个异步方法而不在两个异步方法上都使用 await 时才会引发异常。请为您的异常添加堆栈跟踪,我怀疑您的存储库不是问题(即使您应该像 Simon 在他的回答中所说的那样重写它)。
-
@FedericoDipuma 谢谢你解决了这个问题我再次检查了我的异常跟踪,发现在每次向 api 请求之前,他还做了一些安全措施,这也得到了一个 dbcontext。我用 using(var db = new CompetitionContext()) 更改了所有方法,现在它运行得非常好。
标签: c# entity-framework asynchronous asp.net-web-api