我在 Azure Functions 中将 Entity Framework Core 与 Cosmos DB 提供程序一起使用,当同时调用两个 HTTP 触发的函数时,我收到一个异常,指出
DbContext
是从另一个线程访问的。
这是我的设置:
DbContext
使用 AddDbContext()
方法注册和配置。UnitOfWork
类使用这个 DbContext
,并且它被注册为 scoped
服务。MediatR
RequestHandler
类依赖于此 UnitOfWork
并使用 RegisterServicesFromAssembly()
方法进行注册。程序.cs
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(services =>
{
services.AddDbContext<MyDbContext>(options =>
{
options.UseCosmos(
"https://your-cosmosdb-uri",
"your-cosmosdb-key",
"your-database-name"
);
}, ServiceLifetime.Transient);
services.AddTransient<IUnitOfWork, UnitOfWork>();
services.AddMediatR(cfg =>
cfg.RegisterServicesFromAssembly(typeof(Program).Assembly)
);
})
.Build();
host.Run();
MyFunctions.cs
public class MyFunctions
{
private readonly IMediator _mediator;
public MyFunctions(IMediator mediator)
{
_mediator = mediator;
}
[FunctionName("MyFunctionOne")]
public async Task<IActionResult> RunOne(
[HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req,
CancellationToken cancellationToken)
{
var result = await _mediator.Send(new MyRequest(), cancellationToken);
return new OkObjectResult(result);
}
[FunctionName("MyFunctionTwo")]
public async Task<IActionResult> RunTwo(
[HttpTrigger(AuthorizationLevel.Function, "get"] HttpRequest req,
CancellationToken cancellationToken)
{
var result = await _mediator.Send(new MyRequest(), cancellationToken);
return new OkObjectResult(result);
}
}
UnitOfWork.cs
public class UnitOfWork : IUnitOfWork
{
private readonly MyDbContext _context;
private readonly MyRepository _repo;
public UnitOfWork(MyDbContext context)
{
_context = context;
_repo = new MyRepository(_context);
}
public MyRepository ProductRepository { get => _repo; }
}
MyRequestHandler.cs
public class MyRequestHandler : IRequestHandler<MyRequest, MyResponse>
{
private readonly IUnitOfWork _unitOfWork;
public MyRequestHandler(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public async Task<MyResponse> Handle(MyRequest request, CancellationToken cancellationToken)
{
// Perform operations using UnitOfWork or any other logic
await _unitOfWork.SaveChangesAsync(cancellationToken);
// Create and return the response
return new MyResponse
{
Result = $"Processed: {request.Data}"
};
}
}
对这个线程问题的原因有什么见解吗?
我已经在
Scoped
调用中明确尝试了 Transient
和 AddDbContext()
生命周期,但问题仍然存在。
问题是由使用
ConfigureFunctionsWorkerDefaults()
内部调用的单个扩展方法注册并添加到管道的中间件引起的,它没有使用 ConfigureServices()
方法正确注册。
TLDR - 在
ConfigureServices()
调用中专门注册您的依赖项。