简体   繁体   English

如何关闭未实现 IDisposable 的单例服务

[英]How to Close a Singleton service that does not implement IDisposable

I have a singleton service that talks to a Service Bus.我有一个与服务总线通信的单例服务。 My problem is that I cannot implement IDisposable elegantly since the "Close" calls to the service bus clients are async - CloseAsync() .我的问题是我无法优雅地实现IDisposable因为对服务总线客户端的“关闭”调用是async - CloseAsync()

Thus, my service class also implements a CloseAsync method which defers to the service bus client's CloseAsync .因此,我的服务类还实现了CloseAsync方法,该方法CloseAsync服务总线客户端的CloseAsync From what I can gather my options are:从我可以收集到的选项是:

  1. Implement dispose and block while calling CloseAsync on the client.在客户端调用CloseAsync时实现 dispose 和 block。 Feels wrong.感觉不对。
  2. Initialise a member variable in startup.cs , add that as a Singleton , use ApplicationLifetime to register a ShutDown handler, and close my clients in there.startup.cs初始化一个成员变量,将其添加为Singleton ,使用ApplicationLifetime注册一个ShutDown处理程序,然后在那里关闭我的客户端。 Seems like overkill.好像矫枉过正。 (I've tried this but the code in my ShutDown handler is either not hit, or is not being run) (我已经试过了,但我的ShutDown处理程序中的代码要么没有命中,要么没有运行)
  3. Simply leave it, since the application is closing anyway.只需离开它,因为应用程序无论如何都会关闭。 Tempting, but also feels wrong (I like to clean up).诱人,但也感觉不对(我喜欢清理)。

Is there a way to intercept the disposal of services in the DI container (I'm using the standard Microsoft.Extensions.DependencyInjection.ServiceCollection )?有没有办法拦截 DI 容器中服务的处置(我使用的是标准Microsoft.Extensions.DependencyInjection.ServiceCollection )?

Is it OK to block on an async call within the Dispose method?在 Dispose 方法中阻止异步调用是否可以? That way I can make my class self disposing.这样我就可以让我的班级自我处置。

Is there another way to do this that I am missing?有没有另一种方法可以做到这一点,我失踪了?

If you have a single instance of this object through the lifetime of your application, why do you care about disposing it?如果在应用程序的整个生命周期中只有一个该对象的实例,为什么还要关心处置它呢? When an application closes, its memory space gets reclaimed by the OS, effectively disposing the entire set of application and any resources it may have created.当应用程序关闭时,操作系统会回收其内存空间,从而有效地处理整个应用程序集及其可能创建的任何资源。

IDisposable (explicit disposal) makes sense for types of objects that consume a considerable amount of memory and may be created numerous times (typically in quick succession) during the lifetime of your application; IDisposable (显式处理)对于消耗大量内存并且可能在应用程序的生命周期内多次创建(通常是快速连续)的对象类型有意义; for example, bitmap objects that allocate a large buffer for image data, stream s, and other data carrying/manipulating objects that you'd instantiate many times.例如, bitmap对象为图像数据、 stream s 和其他数据承载/操作对象分配大缓冲区,您将多次实例化。 The sort of things that you'd put in a using block.你放在using块中的那种东西。

Here's a rule of thumb:这是一个经验法则:

You need IDisposable only if: each instance of the object consumes significant amount of memory (think tens of megabytes), you need to create and retain many instances at once, or you need to create many instances in very quick succession.仅在以下情况下才需要IDisposable :对象的每个实例都消耗大量内存(想想几十兆字节),您需要一次创建和保留许多实例,或者您需要非常快速地连续创建许多实例。 In these cases, you'll benefit from manually disposing the object.在这些情况下,您将受益于手动处置对象。 If these don't fit your use case, then the garbage collector will do a more than sufficient job cleaning up unused resources.如果这些不适合您的用例,那么垃圾收集器将完成足够多的工作来清理未使用的资源。

Should I implement IDisposable on a singleton? 我应该在单例上实现 IDisposable 吗?

Thanks @Broots for the useful link.感谢@Broots 提供有用的链接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM