长丰网站建设,山东住房和城乡建设厅官网,wordpress官方论坛,济南建网站公司报价【导读】最近看到小伙伴在.NET Core中用到了析构函数#xff0c;不禁打一疑问#xff0c;大部分情况下#xff0c;即使在.NET Framework中都不会怎么用到析构函数#xff0c;我想在.NET Core中是否还依然有效呢#xff1f;随着时间推移#xff0c;迭代版本更新#xff0… 【导读】最近看到小伙伴在.NET Core中用到了析构函数不禁打一疑问大部分情况下即使在.NET Framework中都不会怎么用到析构函数我想在.NET Core中是否还依然有效呢随着时间推移迭代版本更新有些当初我们脑海里认定的东西可能在当前并不再适用这也就需要我们同步知识更新如今我们所认为可能并不再是往昔我们所认为.NET Core/.NET 5.0 析构函数下面首先来看在.NET Framework中一个很标准的资源释放例子这里我以4.7.2版本为例其他版本一样。创建基于当前应用程序域的指定程序集的指定实例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 CreateInstanceT(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);}}
}
通过如上定义创建指定名称的应用程序域沙箱盒子这样我们则可在此沙箱中创建对应程序集和实例如此则可以其他域完全隔离且独立然后在控制台进行如下调用 var sanBox new CurrentDomainSandbox();var instance sanBox.CreateInstanceProgram();
还未完毕直接运行将抛出如下异常若用于远程传输我们直接将主类继承自MarshalByRefObject就好否则将此类通过Serializable特性标记至于二者区别不详细展开通过上述比较标准的例子我们则可以创建和释放未被使用的对应实例我们看到用到了析构函数但是我们发现最终调用Dispose方法并未做任何处理其实不然问题出在对析构函数概念的理解析构函数在应用程序终止之前将调用尚未被垃圾回收的所有对象的析构函数析构函数本质是终结器如果对象已被释放在合适时机将自动调用Finalize方法除非我们手动通过GC来抑制调用终结器GC.SuppressFinalize但不建议手动调用Finalize方法通过资源释放标准例子想必我们已经知道了析构函数的基本原理接下来我们还是基于上述.NET Framework 4.7.2版本来演示析构函数public class ExampleDestructor
{public ExampleDestructor(){Console.WriteLine(初始化对象);}public void InvokeExampleMethod(){}~ExampleDestructor(){Console.WriteLine(终结对象);}
}
既然析构函数是在应用程序终止前进行调用那么我们在调用上述示例中方法时如下调用var exampleDestructor new ExampleDestructor();exampleDestructor.InvokeExampleMethod();
在.NET Framework中如我们所期望在应用程序卸载时此时会调用析构函数并进行相关打印接下来到.NET Core此时将断点放在析构函数中将不会再调用打印如下好了以上只是我个人猜测接下来我们直接看官方文档进行论证官网对于析构函数链接析构函数规范https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/destructors在.NET Framework应用程序中会尽一切合理努力在程序退出时调用析构函数进行清理调用终结器方法除非进行手动抑制但在.NET Core并不能完全保证此行为通过调用Collect来强制进行垃圾回收但是在大多数情况下应避免此调用因为这可能会导致性能问题。为何出现如此差异呢更详细分析请参看链接.NET Core析构函数理解分析https://github.com/dotnet/runtime/issues/16028根据此链接表述可以这样理解在.NET Core中不会在应用程序终止时运行终结器针对可到达或不可到达的对象根据建议并不能保证所有可终结对象在关闭之前都将被终结。由于上述链接原因存在所以在ECMA的C5.0规范削弱了这一要求因此.Net Core并不会违反此版本规范???? 在应用程序关闭前.NET Framework会尽一切合理努力调用析构函数即终结器进行资源清理但在.NET Core中并不能保证此行为所以在ECMA 语言规范中削弱了这一要求???? 基于上述在.NET Core中使用析构函数并没有实质性意义