【问题标题】:ASP.NET Core/5/6 - When exactly does a "Scoped Service" get disposed?ASP.NET Core/5/6 - “范围服务”究竟何时被处置?
【发布时间】:2022-01-27 05:20:08
【问题描述】:

在 ASP.NET Core/5/6 中,您可以使用 ServiceCollectionServiceExtensions.AddScoped() 方法注册“作用域服务”。

在 Microsoft .NET 文章.NET 中的依赖注入中,它指出:

在处理请求的应用中,作用域服务在请求结束时被释放。 https://docs.microsoft.com/en-us/dotnet/core/extensions/dependency-injection#scoped

他们对“请求结束”的定义是before还是after发送响应(包括标头)?

【问题讨论】:

    标签: asp.net-core asp.net-mvc-5 asp.net-core-mvc


    【解决方案1】:

    答案:之后

    运行测试后,看起来范围内的服务在响应完成发送之后被释放。这是不幸的,因为如果响应是一个大文件,可能需要几秒钟才能完成向客户端的发送,并且服务将不必要地一直保持活动状态(未释放)。如果在响应开始发送之前处置范围内的服务会更好。

    不管怎样,这是我做的测试。

    首先,我创建了一个测试IDisposable 类,该类在实例化和处置时写入控制台:

    public sealed class DisposableTest : IDisposable
    {
        public DisposableTest()
        {
            Console.WriteLine("//////////////////// Created");
        }
        private bool Disposed = false;
        public void Dispose()
        {
            if (!Disposed)
            {
                Disposed = true;
                Console.WriteLine("//////////////////// Disposed");
            }
        }
    }
    

    然后我在 Program.cs 中添加了作用域服务(对于 ASP.NET 6):

    services.AddScoped<DisposableTest>();
    

    接下来,我添加了一些中间件,以便在运行 Response.OnStarting()Response.OnCompleted() 事件时写入控制台:

    app.Use(async delegate (HttpContext Context, Func<Task> Next)
    {
        Context.Response.OnStarting(delegate ()
        {
            Console.WriteLine("//////////////////// Response Started");
            return Task.CompletedTask;
        });
        Context.Response.OnCompleted(delegate ()
        {
            Console.WriteLine("//////////////////// Response Completed");
            return Task.CompletedTask;
        });
        await Next();
    });
    

    最后我将服务添加到 HomeController 的构造函数中,以便访问它:

    public class HomeController : Controller
    {
        public HomeController(DisposableTest TheTest) { }
        public IActionResult Index() { return View(); }
    }
    

    访问/home/index路径后,IIS Express控制台显示如下:

    响应完成发送后,服务似乎已被释放。

    【讨论】:

    • 您可以在响应发送后访问作用域服务,例如HttpResponse.OnCompleted,因此必须在响应发送后处理它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2013-02-24
    • 2015-10-18
    • 1970-01-01
    相关资源
    最近更新 更多