<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          .NET 5.0 析構(gòu)函數(shù)依然有效?

          共 5981字,需瀏覽 12分鐘

           ·

          2021-02-26 21:50

          【導讀】最近看到小伙伴在.NET Core中用到了析構(gòu)函數(shù),不禁打一疑問,大部分情況下,即使在.NET Framework中都不會怎么用到析構(gòu)函數(shù),我想在.NET Core中是否還依然有效呢?


          隨著時間推移,迭代版本更新,有些當初我們腦海里認定的東西可能在當前并不再適用,這也就需要我們同步知識更新,如今我們所認為可能并不再是往昔我們所認為


          .NET Core/.NET 5.0 析構(gòu)函數(shù)


          下面首先來看在.NET Framework中一個很標準的資源釋放例子,這里我以4.7.2版本為例(其他版本一樣)。創(chuàng)建基于當前應用程序域的指定程序集的指定實例


          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);
                }
              }
          }


          通過如上定義創(chuàng)建指定名稱的應用程序域沙箱盒子,這樣我們則可在此沙箱中創(chuàng)建對應程序集和實例,如此則可以其他域完全隔離且獨立,然后在控制臺進行如下調(diào)用


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


          還未完畢,直接運行將拋出如下異常


          若用于遠程傳輸,我們直接將主類繼承自MarshalByRefObject就好,否則將此類通過Serializable特性標記,至于二者區(qū)別不詳細展開


          通過上述比較標準的例子我們則可以創(chuàng)建和釋放未被使用的對應實例,我們看到用到了析構(gòu)函數(shù),但是我們發(fā)現(xiàn)最終調(diào)用Dispose方法,并未做任何處理,其實不然,問題出在對析構(gòu)函數(shù)概念的理解


          析構(gòu)函數(shù):在應用程序終止之前,將調(diào)用尚未被垃圾回收的所有對象的析構(gòu)函數(shù)


          析構(gòu)函數(shù)本質(zhì)是終結(jié)器,如果對象已被釋放,在合適時機將自動調(diào)用Finalize方法,除非我們手動通過GC來抑制調(diào)用終結(jié)器(GC.SuppressFinalize),但不建議手動調(diào)用Finalize方法


          通過資源釋放標準例子,想必我們已經(jīng)知道了析構(gòu)函數(shù)的基本原理,接下來我們還是基于上述.NET Framework 4.7.2版本來演示析構(gòu)函數(shù)

          public class ExampleDestructor
          {
              public ExampleDestructor()
              {
                Console.WriteLine("初始化對象");
              }

              public void InvokeExampleMethod()
              {

              }

              ~ExampleDestructor()
              {
                Console.WriteLine("終結(jié)對象");
              }
          }


          既然析構(gòu)函數(shù)是在應用程序終止前進行調(diào)用,那么我們在調(diào)用上述示例中方法時,如下調(diào)用:

          var exampleDestructor = new ExampleDestructor();

          exampleDestructor.InvokeExampleMethod();



          在.NET Framework中如我們所期望,在應用程序卸載時,此時會調(diào)用析構(gòu)函數(shù)并進行相關打印


          接下來到.NET Core,此時將斷點放在析構(gòu)函數(shù)中,將不會再調(diào)用,打印如下:


          好了,以上只是我個人猜測,接下來我們直接看官方文檔進行論證,官網(wǎng)對于析構(gòu)函數(shù)鏈接

          析構(gòu)函數(shù)規(guī)范

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


          在.NET Framework應用程序中會盡一切合理努力在程序退出時調(diào)用析構(gòu)函數(shù)進行清理(調(diào)用終結(jié)器方法),除非進行手動抑制,但在.NET Core并不能完全保證此行為


          通過調(diào)用Collect來強制進行垃圾回收,但是在大多數(shù)情況下,應避免此調(diào)用,因為這可能會導致性能問題。


          為何出現(xiàn)如此差異呢?更詳細分析請參看鏈接:

          .NET Core析構(gòu)函數(shù)理解分析

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


          根據(jù)此鏈接表述,可以這樣理解:在.NET Core中不會在應用程序終止時運行終結(jié)器(針對可到達或不可到達的對象),根據(jù)建議,并不能保證所有可終結(jié)對象在關閉之前都將被終結(jié)。


          由于上述鏈接原因存在,所以在ECMA的C#5.0規(guī)范削弱了這一要求,因此.Net Core并不會違反此版本規(guī)范


          ??  在應用程序關閉前,.NET Framework會盡一切合理努力調(diào)用析構(gòu)函數(shù)即終結(jié)器進行資源清理,但在.NET Core中并不能保證此行為,所以在ECMA 語言規(guī)范中削弱了這一要求


          ??  基于上述,在.NET Core中使用析構(gòu)函數(shù)并沒有實質(zhì)性意義







          回復 【關閉】
          回復 【實戰(zhàn)】獲取20套實戰(zhàn)源碼
          回復 【被刪】
          回復 【訪客】
          回復 【小程序】學獲取15套【入門+實戰(zhàn)+賺錢】小程序源碼
          回復 【python】學微獲取全套0基礎Python知識手冊
          回復 【2019】獲取2019 .NET 開發(fā)者峰會資料PPT
          回復 【加群】加入dotnet微信交流群

          強烈推薦:8個GitHub 上可以賺錢的小程序!


          微信終于可以免費提現(xiàn)了!


          瀏覽 104
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  好爽毛片一区二区三区色好美 | 影音先锋熟女av 永久免费看黄网址 | 乱伦无码中文字幕 | 91影音先锋 | 亚洲色拍视频 |