为什么Finalize / Destructor示例在.NET Core中不起作用? [英] Why does the Finalize/Destructor example not work in .NET Core?

查看:84
本文介绍了为什么Finalize / Destructor示例在.NET Core中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图学习终结处理和析构函数在C#中的工作方式,我试图在 System.Object.Finalize 示例(复制粘贴代码,未进行任何更改),

I'm trying to learn how finalization and destructor works in C#, I tried to run the code in the System.Object.Finalize example(code copy-pasted, no changes made), but the output is not the same as expected, it shows that the destructor is never called.

代码为:

using System;
using System.Diagnostics;

public class ExampleClass
{
   Stopwatch sw;

   public ExampleClass()
   {
      sw = Stopwatch.StartNew();
      Console.WriteLine("Instantiated object");
   } 

   public void ShowDuration()
   {
      Console.WriteLine("This instance of {0} has been in existence for {1}",
                    this, sw.Elapsed);
   }

   ~ExampleClass()
   {
      Console.WriteLine("Finalizing object");
      sw.Stop();
      Console.WriteLine("This instance of {0} has been in existence for {1}",
                    this, sw.Elapsed);
   }
}

public class Demo
{
   public static void Main()
   {
      ExampleClass ex = new ExampleClass();
      ex.ShowDuration();
   }
}

更新:

当我使用Visual Studio和.net Framework 4.5时,代码按预期工作:
输出与示例相同:

When I use visual studio and .net framework 4.5, the code works as expected: Output same as example:

The example displays output like the following:
   Instantiated object
   This instance of ExampleClass has been in existence for 00:00:00.0011060
   Finalizing object
   This instance of ExampleClass has been in existence for 00:00:00.0036294

当我使用dotnet core应用程序时,代码不起作用:
实际输出为:

When I use dotnet core app, the code does not work: The actual output is:

PS C:\ws\test> dotnet run
    Instantiated object
    This instance of ExampleClass has been in existence for 00:00:00.0056874

那么为什么在.NET Core中有不同之处?

So why this is different in .NET Core?

推荐答案

将来自Peter Duniho和Henk Holterman的评论中的信息汇总并进一步扩展:

Putting together information from comments by Peter Duniho and Henk Holterman and expanding on it further:

此行为违反了C#5.0 Microsoft和 C#6.0的当前草案的规范Microsoft的规范,其中表示:

This behavior is in violation of the C# 5.0 spec from Microsoft and the current draft of the C# 6.0 spec from Microsoft, which say:


在应用程序终止之前,它尚未使用的所有对象的析构函数除非收集的垃圾被抑制(例如,通过调用库方法 GC.SuppressFinalize ),否则将调用收集的垃圾。

Prior to an application's termination, destructors for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example).

但这不是错误,.Net Core故意偏离了.Net Framework行为,如一个corefx问题

But it's not a bug, .Net Core intentionally diverged from the .Net Framework behavior, as explained in a corefx issue:


当前,我们已尽力而为在关闭期间为所有可终结对象(包括可访问对象)运行终结器。为可访问对象运行终结器并不可靠,因为对象处于未定义状态。

Currently, a best-effort attempt is made to run finalizers for all finalizable objects during shutdown, including reachable objects. Running finalizers for reachable objects is not reliable, as the objects are in an undefined state.

...

不要在关闭时运行终结器(对于可到达或不可到达的对象)

Don't run finalizers on shutdown (for reachable or unreachable objects)

在此提议下,不能保证所有可终结对象在关闭前都会被终结。

Under this proposal, it is not guaranteed that all finalizable objects will be finalized before shutdown.

据此,来自ECMA的C#5.0规范削弱了这一点因此,.Net Core不会违反此版本的规范:

Presumably due to this, the C# 5.0 spec from ECMA weakened this requirement, so .Net Core does not violate this version of the spec:


在终止应用程序之前,实现应尽一切合理的努力为其所有尚未被垃圾回收的对象调用终结器(第15.13节),除非这样的清理已被抑制(例如,通过调用库方法 GC.SuppressFinalize )。该实现应记录任何不能保证该行为的条件。

Prior to an application’s termination, an implementation should make every reasonable effort to call finalizers (§15.13) for all of its objects that have not yet been garbage collected, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example). The implementation should document any conditions under which this behavior cannot be guaranteed.

这篇关于为什么Finalize / Destructor示例在.NET Core中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆