Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6639997
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 25, 20262026-05-25T23:37:17+00:00 2026-05-25T23:37:17+00:00

I have 2 assemblies, A containing the Main method and the Foo class, that

  • 0

I have 2 assemblies, A containing the Main method and the Foo class, that uses Bar the class from assembly B:

Bar assembly (assembly B):

public sealed class Bar : IDisposable { 
    /* ... */ 
    public void Dispose() { /* ... */ }
}

Foo class (assembly A):

public class Foo : IDisposable {
    private readonly Bar external;
    private bool disposed;
    public Foo()
    { 
        Console.WriteLine("Foo");
        external = new Bar(); 
    }
    ~Foo()
    { 
        Console.WriteLine("~Foo");
        this.Dispose(false); 
    }
    public void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposed) return;
        if (disposing) external.Dispose();
        disposed = true;
    }
}

Entry point (in assembly A):

class Program
{
    static void Main(string[] args)
    {
        try
        {
            var foo = new Foo();
            Console.WriteLine(foo);
        }
        catch (FileNotFoundException ex) 
        {
            // handle exception
            Console.WriteLine(ex.ToString());
        }
        Console.ReadLine();
    }
}

One of the requirements for this piece of software is that it must gracefully handle the case when a dll is missing.

So when I delete assembly B, and start the application I would expect that the try catch block in the main method handles the FileNotFoundException thrown when the assembly B is missing. Which it sort of does, but that is where the problems start…

When the application continues (a line is entered in the console), the finalizer of the Foo class is called (?!) although no instance of Foo was created – the constructor hasn’t been called. Since there is no instance of the class there is no way for me to call GC.SupressFinalize on the instance externally. The only thing you see in the console output when running the project without the B assembly is ~Foo.

So the questions:

  • Why is the finalizer called even though no instance of the class is created? (to me it makes absolutely no sense! I would love to be enlightened)
  • Is it possible to prevent the application from crashing without a try-catch block in the finalizer? (this would mean refactoring the whole code base…)

Some background: I encountered this problem when writing a plugin enable enterprise application with the requirement that it must continue operation if a dll is missing in the plugin deployment folder and flagging the faulty plugin. I figured that the try-catch block around the external plugin loading procedure would suffice, but obviously it doesn’t, since after catching the first exception the finalizer is still invoked (on the GC thread), which finally crashes the application.

Remark The above code is the most minimalistic code I could write to reproduce the exception in the finalizer.

Remark 2 If I set the breakpoint in the Foo constructor (after deleting Bar’s dll) it is not hit. This means if I would set have a statement in the constructor that creates a critical resource (before newing up Bar) it wouldn’t be executed, hence no need for the finalizer to be called:

// in class Foo
public Foo() {
    // ...
    other = new OtherResource(); // this is not called when Bar's dll is missing
    external = new Bar();        // runtime throws before entering the constructor
}

protected virtual void Dispose(bool disposing) {
    // ...
    other.Dispose();    // doesn't get called either, since I am
    external.Dispose(); // invoking a method on external
    // ...
}

Remark 3
An obvious solution would be to implement the IDisposable like below, but that means breaking the reference pattern implementation (even FxCop would complain).

public abstract class DisposableBase : IDisposable {
    private readonly bool constructed;
    protected DisposableBase() {
        constructed = true;
    }
    ~DisposableBase() {
        if(!constructed) return;
        this.Dispose(false);
    } 
    /* ... */
}   
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-25T23:37:17+00:00Added an answer on May 25, 2026 at 11:37 pm

    Why is the finalizer called even though no instance of the class is created?

    The question makes no sense. Obviously an instance is created; what would the finalizer be finalizing if there wasn’t an instance created? Are you trying to tell us that there’s no “this” reference in that finalizer?

    the constructor hasn’t been called

    The constructor can’t be called because jitting the constructor references a field whose type is missing. How could a constructor body that can’t even be jitted be called?

    You seem to think that just because a constructor cannot be called, that an instance cannot be created. That doesn’t follow logically at all. Clearly there must be an instance before the ctor is called because a reference to that instance is passed to it as “this”. So the memory manager creates an instance – and the garbage collector knows that there’s memory allocated – and then it calls the constructor. If calling the constructor throws an exception – or is interupted by an asynchronous exception such as a thread abort – there’s still an instance there, known to the garbage collector, and therefore in need of finalization when it is dead.

    Since the object will never be assigned to any live variable — it cannot be, since the assignment happens after the ctor, and the ctor threw when the jitter tried to jit it — it will be determined to be dead on the next gen zero collection. It will then be put onto the finalizer queue, which will make it alive.

    the finalizer is still invoked (on the GC thread), which finally crashes the application.

    Then fix the finalizer so that it does not do that.

    Remember, the ctor can be interrupted at any time by an asynchronous exception such as a thread abort. You cannot rely on any invariant of an object being maintained in the finalizer. Finalizers are deeply weird code; you should assume that they can run in arbitrary order on arbitrary threads with the object in an arbitrarily bad state. You are required to write extremely defensive code inside a finalizer.

    If I set the breakpoint in the Foo constructor (after deleting Bar’s dll) it is not hit.

    Correct. As I said, the constructor body cannot even be jitted. How could you hit a breakpoint in a method that cannot even be jitted?

    This means if I would set have a statement in the constructor that creates a critical resource (before newing up Bar) it wouldn’t be executed, hence no need for the finalizer to be called.

    Whether or not you think a finalizer needs to be called is completely irrelevant to the garbage collector. The finalizer might have other semantics than merely cleaning up resources. The garbage collector does not attempt to psychically determine the developer’s intentions and make decisions about whether it needs to call the finalizer or not. The object was allocated and has a finalizer and you did not suppress finalization on it, so it’s gonna be finalized. If you don’t like that then don’t make a finalizer. You made a finalizer because presumably you wanted all instances of the object to be finalized, and so they’re going to be.

    Frankly, I would revisit your basic scenario. The idea that you can safely recover and continue to execute code in an appdomain where required DLLs are missing seems like an extremely bad idea to me. Getting this right is going to be very difficult.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

If I have two assemblies, one containing just business rules (assembly A), and the
I have two assemblies with the same name in the Global Assembly cache, but
I have 2 assemblies: Assembly 1: interface IWeapon { int Might { get; }
So I know now that the debug assemblies have been intentionally left out of
I have two unrelated processes that use .NET assemblies as plugins. However, either process
Because I have several builds sharing some assemblies containing common build tasks, I have
The situation: I have a class library, called RT.Servers , containing a few resources
I have an .NET application with satellite assemblies containing resource to be localized, but
I have a wrapper class for log4net to log across multiple classes and assemblies
I have two assemblies, each with models and a model context. The first assembly

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.