我正在实现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实例的不同线程导致的,但是不能保证实例成员是线程安全的。如果是这种情况,也可能是因为在客户端上评估了嵌套查询,如果是这种情况,请重写查询以避免嵌套调用。
答案 0 :(得分:0)
通过将数据库上下文注入生存期更改为ServiceLifetime.Transient解决了该问题
builder.Services.AddDbContext<CoreDBContext>(options =>
{
options.UseSqlServer(connection, p =>
{
p.MigrationsAssembly("Presistence");
});
},ServiceLifetime.Transient
);