Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec shouldn't promise that finalizers run on application termination #291

Closed
svick opened this issue Jun 24, 2017 · 1 comment · Fixed by #309
Closed

Spec shouldn't promise that finalizers run on application termination #291

svick opened this issue Jun 24, 2017 · 1 comment · Fixed by #309
Assignees

Comments

@svick
Copy link
Contributor

svick commented Jun 24, 2017

In .Net Framework, when an application exits, finalizers for finalizable objects that were not yet garbage collected are called. On the other hand, on .Net Core, this does not happen, see https://github.com/dotnet/corefx/issues/5205.

The .Net Framework behavior is consistent with the draft C# 6.0 specification from MS, but the .Net Core behavior isn't:

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).

The latest draft of the C# 5.0 specification from ECMA weakens this requirement:

Prior to an application’s termination, an implementation should make every reasonable effort to call finalizers (§16.13) 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). The implementation should document any conditions under which this behavior cannot be guaranteed.

This means that .Net Core follows the letter of this version of the spec (as long as it documents that this behavior is never guaranteed). But I think it does not follow the spirit of the spec: .Net Core does not make any effort to call finalizers and so I think that the spec should be weakened even further.

Is the new wording in the ECMA draft good enough? Could someone from the ECMA TC49-TG2, which is currently updating the ECMA version of the spec, comment on this?

This was inspired by an SO question.


To show this behavior:

  1. Create an application consisting of Program.cs:

    using System;
    
    class C
    {
        static void Main()
        {
            new C();
    
            Console.WriteLine("Exiting.");
        }
    
        ~C() => Console.WriteLine("Finalizing.");
    }

    and app.csproj:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFrameworks>net47;netcoreapp1.0</TargetFrameworks>
      </PropertyGroup>
    </Project>
  2. Run the app on .Net Framework and .Net Core to observe the difference:

    > dotnet run -f netcoreapp1.0 # finalizer not called
    Exiting.
    > dotnet run -f net47         # finalizer called
    Exiting.
    Finalizing.
@BillWagner BillWagner self-assigned this Apr 30, 2021
@BillWagner
Copy link
Member

Moving to dotnet/csharpstandard and self assigning.

I already have a similar issue to resolve for the next meeting.

@BillWagner BillWagner transferred this issue from dotnet/csharplang Apr 30, 2021
BillWagner added a commit to BillWagner/csharpstandard that referenced this issue May 4, 2021
Fixes dotnet#176
Fixes dotnet#291

The normative text now declares that running finalizers on exit is implementation specific.

I added an additional *note* that the .NET Framework follows the earlier standard text. (I looked for a definitive statement on the Mono environment, and I found resources that implied both that it did and it didn't follow this guarantee.
BillWagner added a commit that referenced this issue May 5, 2021
…309)

* Remove the guarantee that an implementation runs finalizers on exit.

Fixes #176
Fixes #291

The normative text now declares that running finalizers on exit is implementation specific.

I added an additional *note* that the .NET Framework follows the earlier standard text. (I looked for a definitive statement on the Mono environment, and I found resources that implied both that it did and it didn't follow this guarantee.

* Apply suggestions from code review

Co-authored-by: Jon Skeet <skeet@pobox.com>

Co-authored-by: Jon Skeet <skeet@pobox.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants