ASP.NET Core 中的新任务如何利用依赖注入?

she*_*ild 5 c# multithreading dependency-injection task asp.net-core

我正在为我的 WEBAPI 项目使用 ASP.NET CORE 2.0.5 运行时。在我的实现中,当请求传入时,一个新任务就会开始执行一些繁重的工作,并最终向其他地方的 webapi 发出请求。与此同时,我正在向呼叫者返回成功响应。

问题是,由于繁重的工作需要更长的时间来处理,我无法利用我在 Startup 类中设置的所有 DI 服务,因为原始请求已经返回并且所有 DI 服务都已处理。

有没有办法将我的 IServiceCollection 传递给新任务,或者有更好的方法吗?

更新:

事实证明,并不是所有 DI 服务都被处理掉了。只有这一个:

services.AddTransient<HttpMessageHandler, HttpClientHandler>();
Run Code Online (Sandbox Code Playgroud)

该行用于启用单元测试。没有它,我的 webapi 运行良好,但我的单元测试失败了......

Ale*_*bov 6

Asp.Net Core DI 提供了 3 个服务生命周期选项:

  • 瞬态- 瞬态生命周期服务在每次请求时创建。它们与使用它的服务一起被处理。
  • 作用域- 每个请求创建一次作用域生命周期服务。它们与范围一起被处理。
  • Singleton - Singleton 生命周期服务在第一次被请求时创建。当应用程序还活着时,他们就活着。

因此,您不能传递给后台任务瞬态或作用域服务,因为当主线程停止时它将被释放。但是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
        }));
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 -1

由于依赖项是根据每个请求进行处理的,更好的方法是对“繁重”部分使用后台任务。

当您收到请求时,您可以以某种方式保留数据(一种方法是使用数据库),然后将响应返回给调用者。然后您可以独立使用后台任务。后台任务将定期检查是否存储了任何请求,如果是,它可以执行“繁重”工作,发送请求并清理存储的请求。