当前位置:网站首页>. net core /. Net 5.0 destructor still valid?

. net core /. Net 5.0 destructor still valid?

2020-12-06 13:12:00 Jeffcky

Preface

Recently, I saw my partner in .NET Core The destructor is used in , I can't help but wonder , In most cases , Even in .NET Framework You don't use destructors very much in , I want to .NET Core Is it still valid ? Over time , Iterative version update , Some of the things we thought about in the first place may not be applicable at present , This requires us to update our knowledge synchronously , What we think today may not be what we used to think

.NET Core/.NET 5.0 Destructor

Let's first look at .NET Framework A very standard example of resource release in , Here I use 4.7.2 Version as an example ( The other versions are the same ). Creates a specified instance of the specified assembly based on the current application domain

public class CurrentDomainSandbox : IDisposable
{
    private AppDomain _domain = AppDomain.CreateDomain(
      "CurrentDomainSandbox",
      null,
      new AppDomainSetup
      {
        ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
        ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
      });

    ~CurrentDomainSandbox()
    {
      Dispose(false);
    }

    public T CreateInstance<T>(params object[] args)
      => (T)CreateInstance(typeof(T), args);

    private object CreateInstance(Type type, params object[] args)
    {
      HandleDisposed();

      return _domain.CreateInstanceAndUnwrap(
        type.Assembly.FullName,
        type.FullName,
        ignoreCase: false,
        bindingAttr: 0,
        binder: null,
        args: args,
        culture: null,
        activationAttributes: null);
    }

    public void Dispose()
    {
      Dispose(true);
      GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposing && (_domain != null))
      {
        AppDomain.Unload(_domain);
        _domain = null;
      }
    }

    private void HandleDisposed()
    {
      if (_domain == null)
      {
        throw new ObjectDisposedException(null);
      }
    }
}

Create an application domain sandbox with the specified name as defined above , In this way, we can create corresponding assemblies and instances in this sandbox , In this way, other domains can be completely isolated and independent , Then make the following call in the console

  var sanBox = new CurrentDomainSandbox();
  var instance = sanBox.CreateInstance<Program>();

It's not over yet , Running directly will throw the following exception

  If used for remote transmission , We inherit the main class directly from MarshalByRefObject Just fine , Otherwise, it will pass through Serializable Characteristic marks , As for the difference between the two is not detailed . Through the standard example above, we can create and release the unused corresponding instance , We see the use of destructors , But we found that the final call Dispose Method , Nothing has been done , It's not , The concept of disjunctive function is the problem of understanding

 

Destructor : Before the application terminates , Destructors for all objects that have not been garbage collected will be called . A destructor is essentially a terminator , If the object has been released , Will be called automatically at the right time Finalize Method , Unless we go through it manually GC To suppress the call Terminator (GC.SuppressFinalize), It is not recommended to call Finalize Method

 

Through the resource release standard example , We must have known the basic principle of destructors , Next, we are still based on the above .NET Framework 4.7.2 Version to demonstrate the destructor

public class ExampleDestructor
{
    public ExampleDestructor()
    {
      Console.WriteLine(" Initialize object ");
    }

    public void InvokeExampleMethod()
    {

    }

    ~ExampleDestructor()
    {
      Console.WriteLine(" End object ");
    }
}

Since the destructor is called before the application terminates , So when we call the method in the example above , The following call :

var exampleDestructor = new ExampleDestructor();

exampleDestructor.InvokeExampleMethod();

stay .NET Framework As we expected , When the application is unloaded , This will call the destructor and print it . Next to the .NET Core, Put the breakpoint in the destructor , Will no longer call , Print as follows :

Okay , The above is just my personal guess , Now let's go straight to the official documents to demonstrate , The official website links to destructors

Destructor specification

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors

stay .NET Framework Every reasonable effort is made in the application to call the destructor to clean up when the program exits ( Call the terminator method ), Unless manually inhibited , But in .NET Core There is no guarantee that this behavior . By calling Collect To force garbage collection , But in most cases , This call should be avoided , Because this can lead to performance problems . Why is there such a difference ? For a more detailed analysis, see the link :

.NET Core Destructors understand analysis

https://github.com/dotnet/runtime/issues/16028

According to this statement , It can be understood in this way : stay .NET Core Does not run the terminator when the application terminates ( For reachable or unreachable objects ), According to the suggestion , There is no guarantee that all summable objects will be terminated before they are closed . Due to the above link reasons , So in ECMA Of C#5.0 The norm weakens that requirement , therefore .Net Core It doesn't violate this version of the specification

summary

  Before the application closes ,.NET Framework Will make every reasonable effort to call the destructor, the terminator, for resource cleanup , But in .NET Core There is no guarantee of this behavior , So in ECMA The language specification weakens this requirement

  Based on the above , stay .NET Core There's no real meaning in using a destructor in

版权声明
本文为[Jeffcky]所创,转载请带上原文链接,感谢
https://chowdera.com/2020/12/20201206131127105v.html