我正在实现Queue触发的azure函数 - 我正在使用名为Mediatr的Mediator Pattern库来增强命令查询隔离 - 并根据以下教程使用Azure Function中的最新运行时(2.0.12382.0)构造函数依赖注入https://devkimchi.com/2019/02/22/performing-constructor-injections-on-azure-functions-v2/
对于每个Azure函数触发器,我调用Mediatr CommandHandler
但我收到错误:
“在上一个操作完成之前,第二个操作在此上下文中启动。这通常是由使用相同DbContext实例的不同线程引起的,但实例成员不保证是线程安全的。这也可能是由于要评估的嵌套查询引起的在客户端上,如果是这种情况,则重写查询以避免嵌套调用。“
该错误表明我正在尝试从并行任务访问同一个DbContext
实例。但是我只有一个命令处理程序(Mediatr Handler)和一个查询处理程序。我正在使用构造函数注入
我试图在启动时将Meditr服务更改为瞬态,但在测试azure函数模拟器中的函数时仍会收到相同的错误
启动类
public class StartUp : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
var connection = configuration.GetConnectionString("Default");
builder.Services.AddDbContext<CoreDBContext>(options =>
{
options.UseSqlServer(connection, p =>
{
p.MigrationsAssembly("B12Core.Persistence");
});
}
);
builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>));
builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestPerformanceBehaviour<,>));
builder.Services.AddTransient(typeof(IPipelineBehavior<,>), typeof(RequestValidationBehavior<,>));
builder.Services.AddMediatR(p =>
{
p.AsTransient();
}, typeof(CreateMessageCommand).GetTypeInfo().Assembly);
}
}
完全错误
System.Private.CoreLib:执行函数时出现异常:Function1。 Microsoft.EntityFrameworkCore:在上一个操作完成之前,在此上下文中启动了第二个操作。这通常是由使用相同DbContext实例的不同线程引起的,但实例成员不保证是线程安全的。这也可能是由在客户端上评估的嵌套查询引起的,如果是这种情况则重写查询以避免嵌套调用。
通过将db上下文注入生命周期更改为ServiceLifetime.Transient来解决此问题
builder.Services.AddDbContext<CoreDBContext>(options =>
{
options.UseSqlServer(connection, p =>
{
p.MigrationsAssembly("Presistence");
});
},ServiceLifetime.Transient
);