【问题标题】:Simple Injector ASP.NET Singleton Dispose简单的注入器 ASP.NET Singleton Dispose
【发布时间】:2019-06-18 13:24:33
【问题描述】:

Simple Injector 文档非常清楚地说明了瞬态和单例注册,以及它们将如何被释放等。文档表明,在容器被释放时,除了预先构造的对象之外的所有对象注册的单例都将被释放。

我的问题具体涉及一个单例注册,当 ASP.NET 应用程序被释放时我需要被释放(我在释放该服务时发送任何剩余的消息)。我的大多数注册都是暂时的,并且在处理每个请求时都会被处理。在 VS/IISExpress 中进行调试时,我看不到我的单例何时被释放——或者容器本身何时最终被释放。在我的控制台应用程序和天蓝色服务中,我完成后只需调用 container.Dispose()。 ASP.NET 中的任何线索可用于最后的清理工作?

【问题讨论】:

    标签: asp.net singleton dispose simple-injector


    【解决方案1】:

    对于要处理的单例,您需要在应用程序结束时显式调用Container.Dispose()。例如,这可以在 Global.asax 中的 Application_End 事件中完成。但请注意。

    当该服务被释放时,我会发送任何剩余的消息

    这似乎是一个非常糟糕的主意,因为Application_End 事件没有运行的原因有很多。 IIS 可以非常积极地杀死应用程序,断电和其他硬件故障也会如此。如果发生这种情况,则意味着您将丢失仍在本地缓冲区中的所有消息。

    对于用于应用程序心跳和有时记录的易失性消息,这可能不是问题,但如果这些消息描述了重要的业务事件,您应该使用持久的队列或存储机制。

    在 VS/IISExpress 中调试时,我从来没有看到我的单例何时被释放

    很可能是这样。调试 Web 应用程序时,Web 应用程序永远不会自行停止。如果您停止调试,应用程序突然停止而没有机会运行任何终结器和清理方法,或者当您停止调试时,应用程序继续在后台运行;这仍然意味着您不会看到任何清理工作。

    【讨论】:

    • 我完全同意你对这种方法的问题的看法,但在大多数情况下它总比什么都不做(即丢弃任何未发送的消息)要好。请记住,即使您使用冗余方法,它也不是故障安全的。我要问的是在托管的 IIS ASP.NET 环境中,确保 SimpleInjector 容器已处理的正确方法是什么,所以我至少有机会尝试发送任何本地排队的消息。 OWIN OnAppDisposing 是否等同于 Application_End?
    • 如果丢失消息是个问题,我真的建议你改变你的设计。将这些消息保留在与其余请求运行相同的数据库事务中。这是一种非常常见的方法,可以防止消息丢失。关于 OWIN:我不确定 OnAppDisposing 是做什么的。您必须阅读文档并对此进行测试。
    • 我会再看看这个特定的消息是如何完成的。数据交易。 IIRC,向 Azure ServiceBus(我们使用的)写入消息必须在环境 DB 事务范围之外完成,这违背了这里的目的。见docs.particular.net/nservicebus/azure-service-bus/…。感谢史蒂文的讨论!
    • 看看 NServiceBus 支持的Outbox messaging pattern。它允许将消息存储在本地“事务”队列中,并在确定这样做安全后将其发送到真实的基础设施。
    猜你喜欢
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 2018-10-08
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多