C#的WebAPI异步方面的问题
我这就要求我的WebAPI同时有两个控制台应用程序和我回去在控制台应用程序从我的API后续反应:C#的WebAPI异步方面的问题
第二次手术就这样开始了上下文之前一先前的异步操作完成。在调用此上下文中的另一个方法之前,请使用'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);
}
}
感谢您所有的意见/帮助。
在你的仓库中,你正在创建一个单一的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();
}
}
或确保上下文是每个请求。 –
RegisterType每次调用控制器的构造函数时都应该默认创建一个新的FederationRepository,并且每个请求调用构造函数一次。每个新的'FederationRepository'都会创建一个新的'CompetitionContext'。 –
我试过这个解决方案,但并没有解决问题。 – Nick
我会检查看看是否有导致您的统一登记搞砸,它表现得像一个IFederationRepository是在请求之间共享。尝试在统一注册中明确地设置一个'TransientLifetimeManger'来查看它是否改变了任何东西。 –
@ScottChamberlain我试过这个container.RegisterType(new HierarchicalLifetimeManager());但如果那是你的意思,那也没有解决问题。 –
Nick
'HierarchicalLifetimeManager'是使用绝对错误的管理器,您需要每个解决方案的类的新副本。你需要一个'TransientLifetimeManger' –