Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在c#中,我们可以使用finalize来处理托管源吗?_C#_Garbage Collection_Dispose_Finalize - Fatal编程技术网

在c#中,我们可以使用finalize来处理托管源吗?

在c#中,我们可以使用finalize来处理托管源吗?,c#,garbage-collection,dispose,finalize,C#,Garbage Collection,Dispose,Finalize,根据如何使用IDisposable的模式,Microsoft建议使用finalize来发布非托管源代码。 但如果我们编写一些代码来发布finalize中的托管源代码,会发生什么呢? 也就是说,当GC调用完成以释放某个托管源时,会发生什么情况?这通常是一种不好的做法。在终结器代码中,您不能依赖对象及其托管资源的状态——它们可以被收集或处置/终结。此外,您不能依赖CLR调用Finalize的顺序,这通常是一种不好的做法。在终结器代码中,您不能依赖对象及其托管资源的状态——它们可以被收集或处置/终结

根据如何使用IDisposable的模式,Microsoft建议使用finalize来发布非托管源代码。

但如果我们编写一些代码来发布finalize中的托管源代码,会发生什么呢?
也就是说,当GC调用完成以释放某个托管源时,会发生什么情况?

这通常是一种不好的做法。在终结器代码中,您不能依赖对象及其托管资源的状态——它们可以被收集或处置/终结。此外,您不能依赖CLR调用
Finalize

的顺序,这通常是一种不好的做法。在终结器代码中,您不能依赖对象及其托管资源的状态——它们可以被收集或处置/终结。此外,您不能依赖CLR调用
Finalize

的顺序,为什么(或者更好地说,如何)发布在finalizer中管理的内容?当前对象拥有的所有内容此时都已被视为垃圾,并将在垃圾收集器的下一次运行中收集。当前所做的一切都不能发布,因为其他东西可能仍然引用它。

为什么(或者更好,如何)发布在终结器中管理的东西?当前对象拥有的所有内容此时都已被视为垃圾,并将在垃圾收集器的下一次运行中收集。并且当前所做的而非所拥有的一切都无法发布,因为其他东西可能仍然引用它。

无需为托管代码编写Dispose/Finalize。bcz当对象不再被引用时,CLR将删除它。Dispose方法是为非托管代码(如文件处理程序或数据库命令)编写的。

无需为托管代码编写Dispose/Finalize。bcz当对象不再被引用时,CLR将删除它。Dispose方法是为非托管代码(如文件处理程序或数据库命令)编写的。

一般来说,使用
Finalize
清理外部托管资源是无用的,可能是危险的。当对象终结器运行时,它所拥有的托管资源可能是:

  • 由于运行了终结器,已经清理了它们,在这种情况下,处理它们将是无用的。
  • 尚未清理,但被任何活动对象识别为未引用,在这种情况下,无论当前执行的终结器是否尝试清理它们,它们的终结器都将在适当的时候运行。
  • 仍由其他活动对象使用,在这种情况下,当前运行的终结器不应清理这些对象。 在某些情况下,让终结器调用其他托管对象上的清理代码可能会有所帮助,但这种调用通常仅适用于对象知道彼此内部详细信息的情况,并且通常应使用
    受保护的
    内部
    方法执行,或者使用私下交换的代表。例如,在某些情况下,可能有两个或多个对象相互了解,并且具有必须按特定顺序运行的终结器


    例如,可能有一个类的目的是向USB设备发送数据,另一个类的目的是控制连接到该设备的设备。如果后一类想要确保设备接收到“关机”命令,则可能需要其终结器在USB连接类终结器关闭连接之前发送该命令。处理这个问题最干净的方法可能是让USB连接对象的构造函数接受一个回调,它将从其终结器调用该回调。如果这个类没有这样的特性,事情可能会变得相当棘手。另一种方法可能是将一个对象与包装器分离,该对象保存清理所需的所有信息,以及包装器对象的
    WeakReference
    ,并具有一个计时器滴答事件,如果
    WeakReference
    已停止,该事件将执行清理。如果计时器绑定到创建包装器对象的线程,则即使放弃了包装器对象,也可以执行清理,前提是该线程仍然处于活动状态(如果可能不处于活动状态,则情况会变得更复杂)。

    通常,使用
    Finalize
    清理外部管理的资源是无用的,并且可能是危险的。当对象终结器运行时,它所拥有的托管资源可能是:

  • 由于运行了终结器,已经清理了它们,在这种情况下,处理它们将是无用的。
  • 尚未清理,但被任何活动对象识别为未引用,在这种情况下,无论当前执行的终结器是否尝试清理它们,它们的终结器都将在适当的时候运行。
  • 仍由其他活动对象使用,在这种情况下,当前运行的终结器不应清理这些对象。 在某些情况下,让终结器调用其他托管对象上的清理代码可能会有所帮助,但这种调用通常仅适用于对象知道彼此内部详细信息的情况,并且通常应使用
    受保护的
    内部
    方法执行,或者使用私下交换的代表。例如,在某些情况下,可能有两个或多个对象相互了解,并且具有必须按特定顺序运行的终结器

    例如,可能有一个类的目的是向USB设备发送数据,另一个类的目的是控制连接到该设备的设备。如果后一类想要确保设备接收到“关机”命令,则可能需要其终结器在USB连接类终结器关闭连接之前发送该命令。最干净的处理方法可能是让USB连接对象的构造函数接受它将从