我正在为我的 WEBAPI 项目使用 ASP.NET CORE 2.0.5 运行时。在我的实现中,当一个请求进来时,一个新任务开始做一些繁重的工作,并最终向其他地方的 webapi 发出请求。同时,我将成功响应返回给我的调用者。
问题是,由于繁重的工作需要更长的时间来处理,我无法使用我在 Startup 类中设置的所有 DI 服务,因为原始请求已经返回并且所有 DI 服务都已处理。
有没有办法将我的 IServiceCollection 传递给新任务,或者有更好的方法吗?
更新:
结果并不是每个 DI 服务都被释放了。只有这个:
services.AddTransient<HttpMessageHandler, HttpClientHandler>();
这一行是为了启用单元测试。没有它,我的 webapi 运行良好,但我的单元测试中断...
最佳答案
Asp.Net Core DI 提供了 3 种服务生命周期选项:
- transient - transient 生命周期服务在每次被请求时创建。它们与使用它的服务一起处理。
- Scoped - Scoped 生命周期服务针对每个请求创建一次。它们与范围一起处置。
- 单例 - 单例生命周期服务在首次请求时创建。他们在应用程序运行时就在运行。
因此,您不能将 transient 或作用域服务传递给后台任务,因为它们将在主线程停止时被释放。但是有 IServiceScopeFactory
可以在后台任务执行中为您创建一个范围,您可以在其中安全地解决您的依赖关系,例如:
private readonly IServiceScopeFactory _scopeFactory;
public Service(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void RunBackgroundTask()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(state => {
using (scope = _scopeFactory.CreateScope())
{
var dependencyService = scope.ServiceProvider.GetService(typeof(SecondService));
// do your work here
}));
}
}
关于c# - ASP.NET Core 中的 new Task 是如何利用依赖注入(inject)的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52574636/