当前位置: 首页 > 编程语言 > C#

在单例上使用Dispose清理资源共享

时间:2023-04-10 20:00:28 C#

在单例上使用Dispose清理资源我的问题可能与语义有关,而不是IDisposable的实际使用。我正在实现一个单例类,负责管理在应用程序执行期间创建的数据库实例。当应用程序关闭时,应删除该数据库。现在,删除操作由应用程序关闭时调用的单例的Cleanup()方法处理。当我为Cleanup()编写文档时,令我震惊的是,我描述的是应该使用Dispose()方法来清理资源。我最初没有实现IDisposable,因为它在我的单例中看起来不正确,因为我不想处理单例本身。还没有,但将来可能会出现调用此Cleanup()但单例仍然需要存在的原因。我想我可以包括GC.SuppressFinalize(this);在Dispose方法中使这项工作。所以我的问题是多方面的:1)在单例上实施IDisposable是一个根本上不好的主意吗?2)我是否只是通过使用Cleanup()而不是Dispose()来混合语义,因为我正在处理资源,我真的应该使用dispose吗?3)使用GC.SuppressFinalize(this)实现“Dispose()”;GC.SuppressFinalize(这个);这样我的单身人士实际上并没有被破坏,因为我希望它在清理数据库的调用中幸存下来。简而言之,如果你有一个单例并且你调用handle。在此之后尝试使用它的任何对象都将使用处于处置状态的对象。现在放入,并在应用程序完成后处理对象,不一定是坏事。打电话时必须小心。如果你真的关心清理并且只有一个对它的引用,那么你可以将清理代码放在对象终结器~YourClass中,它只会通过.Net调用,确保不再需要它(当应用程序关闭时,如果它是真正的单例)。我只是通过使用Cleanup()而不是Dispose()来混合语义,因为我正在处理资源,我真的应该使用处理吗?是的,这只是语义。Dispose是用于显示程序处理完对象后需要清理的内容的标准。将使用GC.SuppressFinalize(this)实现“Dispose()”;这样我的单例实际上并没有被破坏,因为我希望它在清理数据库的调用中幸存下来。不,这意味着当你调用dispose方法时,垃圾收集器不会调用对象的自定义终结器。如果单例是使用CAS技术而不是锁创建的,那么为单例实现IDisposable可能是个好主意。像这样的东西。if(instance==null){vartemp=newSingleton();if(Interlocked.CompareExchange(refinstance,temp,null)!=null)&&tempisIDisposable){((IDisposable)temp).Dispose();}}returninstance我们创建了一个临时对象,并尝试了primitivesCompare-and-Swap,所以如果这个临时对象实现了IDisposable,没有地方写实例,我们就需要处理这个临时对象。如果您使用一些繁重的逻辑在其构造函数中创建单例的实例,那么避免锁定可能会很好,但也会产生一些开销。如果您不希望其他代码清理或处置您的对象,请不要给它任何机会。但是,提供某种reset()方法以允许单例重新创建自身(如果使用惰性初始化)可能是个好主意。像这样:publicstaticSingletonGetInstance(){if(instance==null){instance=newSingleton();//这里我们重新评估缓存}returninstance}publicstaticvoidReset(){instance=null;}我同意凯文的回答,但还想补充一点。我对你的说法有点困惑:当应用程序关闭时应该删除这个数据库。你的意思是删除?在毁灭?你在谈论一个真正的(SQL)数据库吗?您必须明白,即使您将清理代码放在终结器或Application_End事件(ASP.NET)中,也不能保证会调用此代码。该过程可以终止,或关闭计算机电源。在应用程序启动时删除数据库似乎更合理,或者至少有一个在启动时进行一些清理的回退机制。虽然终结器是处理资源时进行清理的好地方,但在您的情况下,我们谈论的是应用程序资源。我的意思是,资源可能不会绑定到单个对象(您的单例),而是整个应用程序的一部分。这可能会引起一些抽象的讨论,这可能更像是一个视角问题。我想说的是,当您将该数据库视为应用程序资源时,您不必将初始化和清理绑定到对象,而是绑定到应用程序。在ASP.NET应用程序中,这将是Application_Start和Application_End(global.asax)。在Windows窗体应用程序中,这将是Program.Main。但是,当使用这些机制而不是终结器时,您无法确定清理代码是否会执行。以上就是C#学习教程:使用DisposeonSingleton清理资源共享的所有内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。涉及侵权,请点击维权联系管理员删除。如需转载请注明出处: