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

查看:17
本文介绍了为什么 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	est> 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:

这种行为违反了 Microsoft 的 C# 5.0 规范和 Microsoft 的 C# 6.0 规范的当前草案,其中说:

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)

在这个提议下,不保证所有的 finalizable 对象都会在关闭前被终结.

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天全站免登陆