我在Web服务中实例化了类,在静态成员中,它保留了一些资源。如果我不是静态地持有这些资源,我可能会通过一些IDisposable对象访问它们,我可以在Dispose上释放资源。无论是否坚持这个会话是一个好主意,当一个类型被静态解构时,.NET是否提供任何方法来调用任何清理代码?
请不要随心所欲地回答这个问题"停止在静态会员中保存资源"。我理解静态保留这些信息的缺点,并且我愿意接受后果(我们正在使用它来将处理时间从58小时减少到4小时,以便我们进行一些批处理)。具体问题是:鉴于这种情况,无论如何我还能很好地清理这些资源吗?
编辑: 我知道该类将继续用于剩余的进程,但是使用静态构造函数.NET可以让您在将该类型加载到内存时执行某些操作。你能在另一端做点什么吗?
答案 0 :(得分:3)
这个问题并没有真正意义,过程生命周期中的静态生命,当一个过程结束,然后操作系统清理了所有内容。如果资源不再运行,则该流程无法继续使用资源。
答案 1 :(得分:3)
实际上无法通过托管代码执行此操作。你想要的是处理卸载的程序集,但在大多数情况下都不会发生这种情况。
更详细:
您可以处理AppDomain.DomainUnload事件(http://msdn.microsoft.com/en-us/library/system.appdomain.domainunload.aspx)。这可以处理从托管进程(例如ASP.NET)卸载应用程序域的时间。
但是,如果您是EXE,或主机EXE正在回收,则不会引发此问题。如果设置正确,您可能能够处理本机DLL_PROCESS_DETACH并将其反弹回托管代码,但由于加载程序锁定,您必须非常小心从该上下文执行的操作(触发程序集加载的任何内容都将死锁)。
您可以阅读本文,了解需要清理的内容(提示:不多):http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx
基本上,您唯一需要担心的是将缓冲区刷新到磁盘,如果您需要做更复杂的事情,那么您已经搞砸了。 malloc(),因此new()可能会立即崩溃你的程序。这也适用于托管代码。
答案 2 :(得分:2)
这个静态状态最后一点何时变得重要?此刻,你应该破坏它。
Destruct可能意味着“释放一些非托管内存,向数据库写出缓存并将静态变量设置为null”。
最后一个访问点在不同的应用程序中意味着不同的东西。在ASP.NET应用程序中,您无法可靠地确定此点。当Application_End事件或AppDomain.Unload事件触发时,以先到者为准。在WCF中也是如此。在WinForms应用程序中,您可以在主窗体关闭后或作为主应用程序的最后一行时使用它。
无论如何,你需要自己进行清理。
替代方法:您可以将状态封装到可终结的对象中。它将在AppDomain卸载时清理。如果你编写一个所谓的关键终结器,你几乎可以保证你的清理工作将会执行。
答案 3 :(得分:1)
你不能破坏尚未实例化的东西。
我认为你应该使用Singleton模式而不是静态保存所有数据。
答案 4 :(得分:-1)
如果作为静态成员存储的对象正确实现了IDisposable,那么.net运行时应该在应用程序卸载时处理所有资源。如果任何对象不这样做,那么我建议你创建实现IDisposable的包装类,以便你可以自己清理。