我在一个web服务中实例化了一个类,在一个静态成员中,它持有一些资源。如果我不是静态地持有这些资源,我可能会通过某个IDisposable对象来访问它们,我可以在Dispose上释放这些资源。不管保持这个会话是否是一个好主意,当类型被静态解构时,.NET是否提供了任何方法来调用清理代码?
请不要用“停止在静态成员变量中持有资源”来回答这个问题。我理解静态保存此信息的缺点,并愿意接受其后果(我们正在使用它将某些批处理的处理时间从58小时减少到4小时)。具体的问题是:鉴于这种情况,有没有办法让我很好地清理这些资源?
编辑:我知道这个类将存在于过程的其余部分,但是使用静态构造函数,.NET让你有机会在将类型加载到内存中时执行某些操作。你能在另一端做些什么吗?
发布于 2012-02-08 03:25:56
实际上,从托管代码中无法做到这一点。您想要的是处理正在卸载的程序集,但在大多数情况下,当您希望它这样做时,这并不会发生。
更详细地说:
您可以处理一个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()会立即使您的程序崩溃。这也适用于托管代码。
发布于 2012-02-08 03:16:52
这个问题没有什么意义,静态在进程的整个生命周期中都存在,当一个进程结束时,所有的东西都会被操作系统清理掉。如果进程不再运行,它将无法继续使用资源。
发布于 2012-02-08 03:26:51
什么时候这种静态状态会变得重要呢?在这个时刻,你应该销毁它。
析构可能意味着“释放一些非托管内存,将缓存写出数据库,并将静态变量设置为null”。
最后一个访问点在不同的应用程序中意味着不同的事情。在ASP.NET应用程序中,您无法可靠地确定这一点。当Application_End事件或AppDomain.Unload事件触发时,无论哪个先发生,都会发生。在WCF中也是如此。在WinForms应用程序中,您可以在主窗体关闭后或作为主应用程序的最后一行访问它。
在任何情况下,您都需要自己进行清理。
替代方法:您可以将自己的状态封装到可完成的对象中。它将在AppDomain卸载时被清除。如果你写了一个所谓的关键终结器,你几乎可以保证你的清理工作将会执行。
https://stackoverflow.com/questions/9182362
复制相似问题