c# - ASP.NET Core 中的 new Task 是如何利用依赖注入(inject)的?

标签 c# multithreading asp.net-core dependency-injection task

我正在为我的 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/

相关文章:

c# - 是否需要引用变量才能将它们包含在闭包中?

c# - 如何为 ListView 中的子项目添加颜色? C#

c++ - 从主线程向工作线程发出信号的问题

r - 具有 0 值的 R 矩阵单元格需要多少空间?以及如何处理大矩阵计算

javascript - 自定义验证不触发客户端

c# - 当请求的凭证模式为 'Access-Control-Allow-Origin' 时,响应中 '*' header 的值不得为通配符 'include'

c# - 为什么VB.NET和C#中整数运算结果显示不同的值?

php - 我可以在 PHP 中创建线程吗?

linux - Linux环境下ASP.NET Core网站文件放在哪里

c# - 共享程序集 - 是否需要签名?