从中间件

时间:2016-10-12 02:17:59

标签: postgresql asp.net-core async-await .net-core npgsql

您好,

我有一个运行在postgresql数据库服务器上的EF Core的ASP.NET核心应用程序。我遇到了这个问题:

当我从控制器访问数据库时,一切正常。 但是当我尝试从中间件访问数据库时,会发生异常(在更高的请求负载下):

System.InvalidOperationException: An operation is already in progress.
   at Npgsql.NpgsqlConnector.StartUserAction(ConnectorState newState)
   at Npgsql.NpgsqlCommand.<ExecuteDbDataReaderInternalAsync>d__4.MoveNext()
...

示例代码:

数据库配置

private void ConfigureDatabase(IServiceCollection services)
{
    var connectionString = ConfigObject.Value.DbContextSettings.ConnectionString;
    services.AddDbContext<ApplicationDbContext>(opts => opts.UseNpgsql(connectionString));
}

的DbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, Guid>
  {

        ...

        public DbSet<SomeItem> SomeItems { get; set; }

        ...
  }

中间件

public async Task Invoke(HttpContext context)  
        {
                var test = await _context.SomeItems.FirstOrDefaultAsync();
        }

控制器

public async Task<SomeItem> GetStuff()  
        {
                return await _context.SomeItems.FirstOrDefaultAsync();
        }

我的问题是 - 为什么控制器能够提供许多异步并发请求而不是中间件?我怎样才能让它发挥作用?我现在在异步性和ASP.NET解剖学方面有点迷失。

提前谢谢。

2 个答案:

答案 0 :(得分:1)

在中间件中使用构造函数注入时,如果依赖关系生存期是作用域的,则会导致captive dependency。您使用了ApplicationDbContext并且它是作用域的。所以问题可能就是出于这个原因。为避免这种情况,您可以将依赖项作为参数传递给Invoke方法:

    public async Task Invoke(HttpContext context, ApplicationDbContext _context)  
    {
         var test = await _context.SomeItems.FirstOrDefaultAsync();
    }

答案 1 :(得分:0)

我不确定你为什么会收到错误,但两种方法都不一样。中间件没有返回类型,控制器也没有“SomeItem”#。此外,只需立即返回Async方法并从任务中删除asnyc等待。

  

public async Task GetStuff()
          {                   return await _context.SomeItems.FirstOrDefaultAsync();           }

public Task<SomeItem> GetStuff()  
{
    return _context.SomeItems.FirstOrDefaultAsync();
}