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); 
} 
} 

感谢您所有的意见/帮助。

+3

我会检查看看是否有导致您的统一登记搞砸,它表现得像一个IFederationRepository是在请求之间共享。尝试在统一注册中明确地设置一个'TransientLifetimeManger'来查看它是否改变了任何东西。 –

+0

@ScottChamberlain我试过这个container.RegisterType (new HierarchicalLifetimeManager());但如果那是你的意思,那也没有解决问题。 – Nick

+1

'HierarchicalLifetimeManager'是使用绝对错误的管理器,您需要每个解决方案的类的新副本。你需要一个'TransientLifetimeManger' –

在你的仓库中,你正在创建一个单一的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(); 
    } 
} 
+0

或确保上下文是每个请求。 –

+0

RegisterType每次调用控制器的构造函数时都应该默认创建一个新的FederationRepository,并且每个请求调用构造函数一次。每个新的'FederationRepository'都会创建一个新的'CompetitionContext'。 –

+0

我试过这个解决方案,但并没有解决问题。 – Nick