微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C#一次性问题

如何解决C#一次性问题

| 例如,如果我忘记编写
using
语句,则垃圾收集器是否会自动释放与某些ѭ0associated实例关联的非托管资源(无论是什么)? 显然,我不知道何时会发生这种情况,但是当我不关心那些资源并且最终将它们处置时,可以将ѭ0保留为
GC
很好吗?     

解决方法

  例如,如果我忘记使用using语句编写,垃圾收集器是否会自动释放与某个IDisposable实例关联的非托管资源(无论是什么)。 通常,但不一定。一次性资源的作者需要做正确的事。   显然,我不知道何时会发生这种情况,但是当我不关心那些资源并且最终将它们处置时,可以将IDisposable留给GC是否可以? 您的问题以虚假为前提。垃圾收集器永远不会调用Dispose。而是,垃圾收集器将调用析构函数(如果愿意,可以使用\“ finalizer \”)。它是析构函数,可能会或可能不会为健忘的用户调用Dispose。 您的问题还表明态度不好。您可能不在乎资源是否延迟释放,但是另一个程序当然可以在意!如果您的客户运行的两个程序都试图访问相同的非托管资源,一个由您编写,另一个由其他人编写,该怎么办?做一个好公民;处理完这些资源后,请立即释放它们,以便其他程序可以使用它们。这是“使用”的真正目的-通过确保快速回收稀缺资源来保持礼貌。 如果用户忘记调用Dispose,则Dispose模式的正确实现将确保析构函数清除非托管资源,并确保析构函数在记住时不会清除资源。 如果您是为拥有非托管资源的类编写Dispose实现的人,则在用户未正确调用Dispose的情况下,有责任正确获取析构函数代码。编写此代码的正确方法已得到充分证明。根据规律。有关一些有用的链接,请参见乔恩的评论。 还要注意,如果您正在编写这样的类,则还必须使它在用户无法调用Dispose的方案中工作。例如,假设构造函数分配了两个非托管资源,并且在第一个和第二个分配之间,抛出了一个异常并将其捕获到构造函数之外。这样,用户将无法调用Dispose,因为在构造函数成功运行之后,将发生新对象引用的分配,而构造函数从未成功完成运行。如何释放第一个非托管资源?只有析构函数可以释放它。面对这种情况,析构函数必须强大。被销毁的对象可能永远不会被完全构造,因此您不能依赖于构造函数的任何不变性。     ,是的,它们最终会被清洗。仅在需要确定性的资源清理时(例如用于GDI,Sql和其他基于系统句柄的代码)或用于可能占用大量内存的对象(如“ 5”)时,才需要使用“ 1”(he ..)。 编辑:这是假设您正确实现了
Dispose
模式并使用了析构函数调用
Dispose
。     ,如果对象通过在终结器中包括对Dispose方法的条件调用来正确实现IDisposable接口,则GC将在收集过程中触发对象的处置(通过终结器)。 某些事情导致这种情况不会发生,但是如果遵循标准模式,则在大多数情况下它应该起作用。 如果对象在终结器中不包含处置代码,则所有赌注均关闭。在太阳超新星爆发之前,未经管理的资源可能一直没有得到处置。     ,不,不一定。这取决于您如何获得非托管资源。 如果您可以直接处理非托管资源(可能是
IntPtr
),那么您应该拥有终结器或使用
SafeHandle
...否则,您肯定会泄漏非托管资源。 如果您的类型仅引用了类似“ 10”的内容,那么您应该期望该类型具有终结器。 现在,很少需要从您的类型内部直接访问非托管资源,并且,如果您使用的是框架类型,它们确实应该进行适当的清理(但不确定)。仍然有可能。     ,系统库中的任何“ 0”将在完成后自行处置(或至少将采取与处置相同的大多数步骤)。 第三方内容无法保证-例如,如果您正在使用一些提供给您句柄的C库接口,例如,直到库被卸载之前,这些句柄可能都不会被清理掉。发生在应用出口)。但是,通常忘记使用ѭ6或enough1ѭ(或者甚至不知道或不在乎某种类型是可抛弃的)已经足够普遍了,没有解释它的.net库编写得很糟糕,IMO。     ,创建对象时,如果它覆盖Object.Finalize,则系统会将其添加到已注册终结器的对象列表中。除非或直到在它们上调用GC.SuppressFinalize,否则将删除列表中的对象以及它们直接或间接引用的对象,否则将它们从列表中删除。如果系统注意到这样的对象符合消除条件,但存在于可终结对象列表中,则该系统将从具有已注册终结器的对象列表中删除,并将其添加到应具有终结器的对象列表中例程尽快调用。每当后一个列表为非空时,系统将在此处执行对象的Finalize例程。 请注意,垃圾收集器实际上并没有处理任何事情,它所做的只是调用已注册完成的对象的Finalize例程。尽管许多类型的对象都具有Finalize例程,这些例程可以确保在错误丢弃它们后进行清理,但是Finalization可能会充满危险。很少会在正确的时间最终确定对象。它们往往要等到废弃后很长时间才能完成,在某些情况下,它们可能会在资源仍在使用时完成。因此,避免依赖终结器是明智的。在某些情况下有必要,但几乎总是很讨厌。 顺便说一句,请注意,如果某个类的对象直接订阅使用寿命更长的对象的事件,则以前的对象(事件订阅者)或它们持有直接或间接引用的任何对象都将没有资格进行消除或最终确定直到后一个对象完成。尽管可能有人争辩说,如果所有类都被放弃,则应该自己清理,但要确保事件订阅者可以发现已被放弃,则需要创建和使用包装对象。在正确使用该类的情况下,这将增加相当大的复杂性并损害性能。当不使用包装对象时,尝试使用终结器清理事件将毫无意义。在活动发布者有资格之前,带有悬挂事件的类将不符合收集条件,一旦发生这种情况,以前的类是否取消订阅都无关紧要。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。