Bitir ve İmha Et


Yanıtlar:


121

Diğerleri zaten Disposeve Finalize(btw Finalizeyöntemi hala dil spesifikasyonunda bir yıkıcı olarak adlandırılır) arasındaki farkı kaplamıştır , bu yüzden sadece Finalizeyöntemin kullanışlı olduğu senaryolar hakkında biraz ekleyeceğim .

Bazı tipler, tek kullanımlık kaynakları kullanmanın kolay olduğu ve tek bir işlemle elden çıkarılacağı bir şekilde kapsamaktadır. Genel kullanım genellikle şu şekildedir: aç, oku veya yaz, kapat (At). Yapıya çok iyi uyuyor using.

Diğerleri biraz daha zor. WaitEventHandlesörnekler için bir iş parçacığından diğerine sinyal göndermek için kullanıldığından böyle kullanılmaz. O zaman soru Disposebunlara kimi çağırmalı ? Bunlar gibi bir koruma türü olarak Finalize, örnek artık uygulama tarafından başvurulmadığında kaynakların atılmasını sağlayan bir yöntem uygular .


60
Bu onaylanmış cevabı anlayamadım. Hala farklı olanı bilmek istiyorum. Ne olduğunu?
Ismael

22
@Ismael: Gerekçelendirilebilecek en büyük durum Finalize, bir kaynağı canlı tutmakla ilgilenen birkaç nesne olduğunda, ancak kaynağa ilgi duymayı bırakan bir nesnenin, sonuncusu. Bu durumda, Finalizegenellikle sadece kimse nesneye ilgi duymadığında ateş eder. Gevşek zamanlaması Finalizedosyalar ve kilitler gibi mantar olmayan kaynaklar için korkunçtur, ancak mantar kaynakları için uygun olabilir.
supercat

13
Harika bir yeni (benim için) kelime için supercat'e +1. Bağlam oldukça açık bir şekilde ortaya koydu, ancak geri kalanımız için wikipedia şöyle diyor: "Mantarlık, bireysel birimleri tatlı ham petrol gibi karşılıklı ikame yeteneğine sahip bir malın veya malın mülkiyeti. bir şirket, tahviller, değerli metaller veya para birimleri. "
Jon Coombs

5
@JonCoombs: Bu oldukça doğru olsa da, "mantar kaynağı" teriminin, serbest bırakılıncaya veya serbest bırakıldıktan veya serbest bırakıldıktan sonra tekrar serbestçe değiştirilebilene kadar serbestçe değiştirilebilen şeylere uygulandığını belirtmek gerekir . Sistem bir kilit nesnesi havuzuna sahipse ve kod, bazı varlıklarla ilişkilendirdiği bir tanesini alırsa, o zaman herkes o kilitle o varlıkla ilişkilendirmek amacıyla o kilide bir başvuruda bulunduğunda , bu kilit ile değiştirilemez başka. Eğer korunan varlık hakkında umurunda tüm kod kilidi terk, ancak, ...
supercat

... o zamana kadar başka bir varlıkla ilişkilendirilene kadar serbestçe yer değiştirebilirdi.
supercat

135

Sonlandırıcı yöntemi, nesneniz çöp toplandığında çağrılır ve bunun ne zaman olacağının garantisi yoktur (zorlayabilirsiniz, ancak performansa zarar verir).

DisposeÖte yandan yöntem temizlemek ve edindiğiniz tüm kaynaklarını (yönetilmeyen veri, veritabanı bağlantıları, dosya kolları, vb) kodu ile yapılır an serbest bırakabilirsiniz böylece sınıf oluşturulmuş kod tarafından çağrılacak anlamına gelir nesneniz.

Standart uygulama uygulamaktır IDisposableve Disposeböylece nesnenizi bir usingifadede kullanabilirsiniz. Gibi using(var foo = new MyObject()) { }. Ve sonlandırıcınızda, Disposearama kodunun sizi atmayı unutması durumunda ararsınız.


17
Sonlandırma uygulamanızdan Atma çağrılması konusunda biraz dikkatli olmanız gerekir - Atma ayrıca, sonlandırıcından dokunmak istemediğiniz yönetilen kaynakları da zaten sonlandırılmış olabileceğinden imha edebilir.
itowlson

6
@itowlson: Nesnelerin iki kez atılabileceği varsayımıyla birlikte null olup olmadığını kontrol etmek (ikinci çağrı ile hiçbir şey yapmadan) yeterince iyi olmalıdır.
Samuel

7
Standart IDisposal örüntüsü ve isteğe bağlı olarak yönetilen bileşenleri imha etmek için bir Dispose (bool) uygulamasının bu sorun için yeterli olduğu görülmektedir.
Brody

Yıkıcıyı (~ MyClass () yöntemi) uygulamak için hiçbir neden yoktur ve daha ziyade her zaman Dispose () yöntemini uygular ve çağırır. Yoksa yanılıyor muyum? Her ikisinin de uygulanması gerektiğinde birisi bana bir örnek verebilir mi?
dpelisek

66

Sonlandırma, bir nesneyi geri çağırdığında çöp toplayıcı tarafından çağrılan geri döndürmez yöntemdir. Amaç, GC'nin nesneye dönene kadar süresiz olarak bekletilmesinden ziyade artık gerekli olmadığında değerli yerel kaynakları (pencere tutamaçları, veritabanı bağlantıları, vb.) Serbest bırakmak için uygulamalar tarafından çağrılan "deterministik temizleme" yöntemidir.

Bir nesnenin kullanıcısı olarak her zaman Dispose öğesini kullanırsınız. Sonuçlandırma GC içindir.

Bir sınıfın uygulayıcısı olarak, elden çıkarılması gereken yönetilen kaynaklara sahipseniz, Dispose uygularsınız. Yerel kaynaklara sahipseniz, hem Dispose hem de Finalize yöntemlerini uygularsınız ve her ikisi de yerel kaynakları serbest bırakan ortak bir yöntem çağırır. Bu deyimler genellikle çağrıları true ile birlikte imha eden ve false ile çağrıları sonlandıran özel bir Dispose (bool çöpe) yöntemi ile birleştirilir. Bu yöntem her zaman yerel kaynakları serbest bırakır, ardından eleme parametresini denetler ve doğruysa yönetilen kaynakları atar ve GC.SuppressFinalize öğesini çağırır.



2
Kendi kendini temizleyen ("yönetilen") ve kendi kendini temizlemeyen ("yönetilmeyen") bir karışımın bulunduğu sınıflar için orijinal önerilen model uzun süredir eskimiş. Daha iyi bir model, yönetilmeyen her kaynağı, temizlenmesi için gerekli olmayan hiçbir şeye güçlü referansları olmayan kendi yönetilen nesnesine ayrı ayrı sarmaktır. Sonlandırılabilir bir nesnenin doğrudan veya dolaylı güçlü bir referansı olduğu her şey, GC ömrünü uzatacaktır. Temizlik için gerekli olan şeylerin kapsüllenmesi, olmayan şeylerin GC ömrünü uzatmaktan kaçınacaktır.
supercat

2
@JCoombs: Disposeiyi ve doğru şekilde uygulamak genellikle kolaydır. Finalizekötüdür ve doğru şekilde uygulanması genellikle zordur. Diğer şeylerin yanı sıra, GC hiçbir nesnenin kimliğinin o nesneye herhangi bir referans olduğu sürece "geri dönüştürülmesini" sağlayamayacağından Disposable, bazıları zaten temizlenmiş olabilecek bir grup nesneyi temizlemek kolaydır. sorun değil; Disposeönceden çağrılmış olan bir nesneye yapılan herhangi bir başvuru , zaten çağrılmış olan bir nesneye başvuru olarak kalacaktır Dispose.
supercat

2
@JCoombs: Buna karşın, yönetilmeyen kaynakların genellikle böyle bir garantisi yoktur. Nesne Fred# 42 dosya tanıtıcısına sahipse ve onu kapatırsa, sistem aynı numarayı başka bir varlığa verilen dosya tanıtıcısına ekleyebilir. Bu durumda, # 42 dosya tanıtıcısı Fred'in kapalı dosyasına değil, diğer varlık tarafından etkin olarak kullanılan dosyaya başvurur; için Fredyakın sap # 42 denemek için tekrar felaket olur. Yönetilmeyen bir nesnenin henüz serbest bırakılıp bırakılmadığını% 100 güvenilir şekilde takip etmeye çalışılabilir. Birden fazla nesneyi takip etmeye çalışmak çok daha zordur.
supercat

2
@JCoombs: Her yönetilmeyen kaynak ömrünü, kaynak kullanıma sunulmuş olup olmadığını bilmez sonra dış kodunu kontrol hiçbir şey yapmaz ama kendi sarıcı nesnesine yerleştirilen, ancak olması gerektiğini bilir edilirse zaten olmadıysa , güvenli bir şekilde sarma nesnesi onu serbest bırakmak için sorabilirsiniz; sarma nesnesi bunu yapıp yapmadığını bilir ve isteği gerçekleştirebilir veya yok sayabilir. GC'nin sargıya yapılan bir referansın sargıya her zaman geçerli bir referans olacağını garanti etmesi çok yararlı bir garantidir.
supercat

43

Sonuçlandırmak

  • Finalizers hep olmalı protecteddeğil, publicya privateyöntem doğrudan uygulamanın kodundan çağrılamaz böylece aynı zamanda, bir çağrı yapabilir base.Finalizeyöntemle
  • Sonlandırıcılar yalnızca yönetilmeyen kaynakları serbest bırakmalıdır.
  • Çerçeve, bir sonlandırıcının herhangi bir örnek üzerinde çalışacağını garanti etmez.
  • Kesinlikle sonlandırıcılara bellek ayırmayın veya sonlandırıcılardan sanal yöntemler çağırın.
  • Sonlandırıcılarda senkronizasyondan ve işlenmeyen istisnaları yükseltmekten kaçının.
  • Sonlandırıcıların yürütme sırası belirleyici değildir; başka bir deyişle, sonlandırıcınızda hala mevcut olan başka bir nesneye güvenemezsiniz.
  • Sonlandırıcıları değer türleri üzerinde tanımlamayın.
  • Boş yıkıcılar yaratmayın. Başka bir deyişle, sınıfınızın yönetilmeyen kaynakları temizlemesi gerekmedikçe ve bir tanesini tanımlarsanız, bazı işler yapması gerekmediği sürece hiçbir zaman açıkça bir yıkıcı tanımlamamalısınız. Daha sonra, artık yıkıcıdaki yönetilmeyen kaynakları temizlemeniz gerekmiyorsa, tamamen kaldırın.

Elden çıkarmak

  • IDisposableSonlandırıcı bulunan her tipte uygulayın
  • DisposeYönteme çağrı yaptıktan sonra bir nesnenin kullanılamaz hale getirildiğinden emin olun . Başka bir deyişle, Disposeyöntem çağrıldıktan sonra bir nesneyi kullanmaktan kaçının .
  • Bunlarla işiniz bittiğinde Disposetüm IDisposabletürleri arayın
  • İzin Disposehataları artırmadan defalarca çağrılacak.
  • Bastırma daha sonra içinden sonlandırıcıyı çağrıları Disposekullanan yöntemin GC.SuppressFinalizeyöntemi
  • Tek kullanımlık değer türleri oluşturmaktan kaçının
  • DisposeYöntemlerin içinden istisnalar atmaktan kaçının

Atma / Sonlandırılmış Desen

  • Microsoft, her iki uygulamak önerir Disposeve Finalizeyönetilmeyen kaynakları ile çalışırken. FinalizeUygulama aday olacağını ve kaynaklar hala nesne bir geliştirici aramaya ihmal eğer çöp bile toplanan olduğunda serbest bırakılacağı Disposeaçıkça yöntemi.
  • FinalizeYöntemdeki yöntemlerin yanı sıra yönetilmeyen kaynakları da temizleyin Dispose. Ayrıca, Disposebu sınıf içinde bileşenler olarak sahip olduğunuz herhangi bir .NET nesnesi için yöntemi (üye olarak yönetilmeyen kaynaklara sahip olan) yöntemden çağırın Dispose.

17
Aynı cevabı her yerde okudum ve hala her birinin amacının ne olduğunu anlayamıyorum. Kuralları sadece kurallardan sonra okurum, başka bir şey değil.
Ismael

@Ismael: ve ayrıca yazar MSDN'den bazı metinleri kopyalayıp yapıştırmak dışında hiçbir şey eklemiyor.
Tarık

@tarik Daha önce öğrendim. Ben bunu sordum o zaman "söz" anlayışı var mıydı.
Ismael

31

Bu nesne artık kullanılmadığında sonlandırma GC tarafından çağrılır.

Dispose, bu sınıftaki kullanıcının kaynakları serbest bırakmak için çağırabileceği normal bir yöntemdir.

Kullanıcı Dispose'i aramayı unuttuysa ve sınıfta Finalize uygulanmışsa GC çağrıldığından emin olur.


3
En temiz cevap
dariogriffo

19

MCSD Sertifikasyon Araç Seti (sınav 70-483) sayfa 193 kitabından bazı anahtarlar var:

yıkıcı ≈ (neredeyse eşittir) base.Finalize() , Destructor, destructor kodunu yürüten ve sonra temel sınıfın Finalize yöntemini çağıran Finalize yönteminin geçersiz kılma sürümüne dönüştürülür. O zaman ne zaman çağrılacağını bilemez tamamen deterministik olmayan çünkü GC bağlıdır.

Bir sınıf yönetilen ve yönetilmeyen kaynak içermiyorsa , onu uygulamamalı IDisposableveya yıkıcıya sahip olmamalıdır .

Eğer sınıf sadece kaynakları yönetmişse , uygulamalı IDisposableama yıkıcı olmamalıdır. (Yıkıcı yürütüldüğünde, yönetilen nesnelerin hala var olduğundan emin olamazsınız, bu yüzden Dispose()yöntemlerini yine de çağıramazsınız .)

Sınıfta yalnızca yönetilmeyen kaynaklar varsa , IDisposableprogramın çağrılmaması durumunda uygulanması ve bir yıkıcıya ihtiyacı vardır Dispose().

Dispose()yöntemi birden fazla çalıştırmak için güvenli olmalıdır. Daha önce çalıştırılıp çalıştırılmadığını takip etmek için bir değişken kullanarak bunu başarabilirsiniz.

Dispose()hem yönetilen hem de yönetilmeyen kaynakları serbest bırakmalıdır .

Yıkıcı yalnızca yönetilmeyen kaynakları serbest bırakmalıdır . Yıkıcı yürütüldüğünde, yönetilen nesnelerin hala var olduğundan emin olamazsınız, bu yüzden yine de Dispose yöntemlerini çağıramazsınız. Bu, protected void Dispose(bool disposing)sadece yönetilen kaynakların serbest bırakıldığı (atıldığı) kanonik desen kullanılarak elde edilir disposing == true.

Kaynakları serbest bıraktıktan sonra, Dispose()çağırmalıGC.SuppressFinalize , böylece nesne sonlandırma sırasını atlayabilir.

Yönetilmeyen ve yönetilen kaynaklara sahip bir sınıf için uygulama örneği:

using System;

class DisposableClass : IDisposable
{
    // A name to keep track of the object.
    public string Name = "";

    // Free managed and unmanaged resources.
    public void Dispose()
    {
        FreeResources(true);

        // We don't need the destructor because
        // our resources are already freed.
        GC.SuppressFinalize(this);
    }

    // Destructor to clean up unmanaged resources
    // but not managed resources.
    ~DisposableClass()
    {
        FreeResources(false);
    }

    // Keep track if whether resources are already freed.
    private bool ResourcesAreFreed = false;

    // Free resources.
    private void FreeResources(bool freeManagedResources)
    {
        Console.WriteLine(Name + ": FreeResources");
        if (!ResourcesAreFreed)
        {
            // Dispose of managed resources if appropriate.
            if (freeManagedResources)
            {
                // Dispose of managed resources here.
                Console.WriteLine(Name + ": Dispose of managed resources");
            }

            // Dispose of unmanaged resources here.
            Console.WriteLine(Name + ": Dispose of unmanaged resources");

            // Remember that we have disposed of resources.
            ResourcesAreFreed = true;
        }
    }
}

2
Bu güzel bir cevap! Ama bunun yanlış olduğunu düşünüyorum: "yıkıcı GC.SuppressFinalize çağırmalıdır". Bunun yerine public Dispose () yöntemi GC.SuppressFinalize öğesini çağırmamalı mı? Bkz. Docs.microsoft.com/tr-tr/dotnet/api/… Bu yöntemin çağrılması, çöp toplayıcının Object.Finalize (yıkıcı tarafından geçersiz kılınan) öğesini çağırmasını önler.
Ewa

7

Zamanın% 99'u da endişelenmenize gerek yok. :) Ancak, nesneleriniz yönetilmeyen kaynaklara (örneğin pencere tanıtıcıları, dosya tanıtıcıları) başvuru içeriyorsa, yönetilen nesnenizin bu kaynakları serbest bırakması için bir yol sağlamanız gerekir. Sonlandırma, kaynakları serbest bırakma üzerinde örtük kontrol sağlar. Çöp toplayıcı tarafından çağrılır. Dispose, kaynakların serbest bırakılması üzerinde açık bir kontrol sağlamanın bir yoludur ve doğrudan çağrılabilir.

Çöp Toplama konusu hakkında öğrenilecek çok şey var , ama bu bir başlangıç.


5
Eğer: Ben oldukça emin C # uygulamalarının% 1'den fazla veritabanlarını kullanmak değilim sahip ıdisposable SQL şeylere endişe etmek.
Samuel

1
Ayrıca, IDisposable'ları kapsüllerseniz IDisposable'ı uygulamalısınız. Muhtemelen diğer% 1'i kapsar.
Darren Clark

@Samuel: Veritabanlarının bununla ne ilgisi olduğunu anlamıyorum. Bağlantıları kapatmaktan bahsediyorsanız, sorun değil, ama bu farklı bir mesele. Bağlantıları zamanında kapatmak için nesneleri elden çıkarmanız gerekmez.
JP Alioto

1
@JP: Fakat Using (...) deseni başa çıkmayı çok daha kolaylaştırıyor.
Brody

2
Kabul etti, ama tam olarak bu. Kullanan desen, Atma çağrısını sizin için gizler.
JP Alioto

6

Sonlandırıcı örtülü temizleme içindir - bir sınıf kesinlikle temizlenmesi gereken kaynakları yönettiğinde kullanmalısınız , aksi takdirde tutamak / bellek vb.

Bir sonlandırıcıyı doğru şekilde uygulamak çok zordur ve mümkün olduğunca kaçınılmalıdır - SafeHandlesınıf (.Net v2.0 ve üstü için geçerlidir) artık çok nadiren (eğer varsa) artık bir sonlandırıcı uygulamanız gerektiği anlamına gelir.

IDisposableArayüz açık temizleme içindir ve çok daha yaygın olarak kullanılan - onlar bir nesneyi kullanmayı bitirdikten zaman kullanıcıların açıkça serbest bırakmak ya da temizleme kaynakları sağlamak için bu kullanmalısınız.

Bir sonlandırıcıya sahipseniz, IDisposablekullanıcılara bu kaynakları toplanan nesnenin çöp toplanmış olması durumunda olduğundan daha çabuk yayınlamasına izin vermek için arayüzü de uygulamanız gerektiğini unutmayın .

Sonlandırıcılar ve konusunda en iyi ve en eksiksiz öneriler kümesi olarak düşündüğüm şeyler için DG Güncellemesi: İmha, Sonlandırma ve Kaynak Yönetimi bölümüne bakın IDisposable.


3

Özet -

  • Yönetilmeyen kaynaklara referans varsa sınıfınız için bir sonlandırıcı yazarsınız ve bu sınıfın bir örneği otomatik olarak çöp toplandığında bu yönetilmeyen kaynakların serbest bırakıldığından emin olmak istersiniz . Bir nesnenin Finalizer'ını açık bir şekilde çağıramayacağınızı unutmayın - çöp toplayıcı tarafından gerekli gördüğü zaman ve zamanda otomatik olarak çağrılır.
  • Öte yandan, sınıfınız yönetilmeyen kaynaklara başvuruda bulunuyorsa ancak çöp toplayıcısının devreye girmesini beklemek istemiyorsanız, IDisposable arabirimini uygularsınız (ve dolayısıyla sınıfınız için bir sonuç olarak Dispose () yöntemini tanımlarsınız). (bu her zaman olabilir - programlayıcının kontrolünde değil) ve işiniz biter bitmez bu kaynakları serbest bırakmak istersiniz. Böylece, bir nesnenin Dispose () yöntemini çağırarak yönetilmeyen kaynakları açıkça serbest bırakabilirsiniz.

Ayrıca, başka bir fark - Dispose () uygulamasında, yönetilen kaynakları da serbest bırakmanız gerekirken , Finalizer'da yapılmamalıdır. Bunun nedeni, nesnenin başvurduğu yönetilen kaynakların, sonlandırılmaya hazır olmadan önce zaten temizlenmiş olmalarıdır.

Yönetilmeyen kaynakları kullanan bir sınıf için en iyi uygulama, bir geliştiricinin nesneyi açıkça atmayı unutması durumunda, hem Dispose () yöntemi hem de Finalizer - bir geri dönüş olarak kullanılacak şekilde tanımlamaktır. Her ikisi de yönetilen ve yönetilmeyen kaynakları temizlemek için paylaşılan bir yöntem kullanabilir:

class ClassWithDisposeAndFinalize : IDisposable
{
    // Used to determine if Dispose() has already been called, so that the finalizer
    // knows if it needs to clean up unmanaged resources.
     private bool disposed = false;

     public void Dispose()
     {
       // Call our shared helper method.
       // Specifying "true" signifies that the object user triggered the cleanup.
          CleanUp(true);

       // Now suppress finalization to make sure that the Finalize method 
       // doesn't attempt to clean up unmanaged resources.
          GC.SuppressFinalize(this);
     }
     private void CleanUp(bool disposing)
     {
        // Be sure we have not already been disposed!
        if (!this.disposed)
        {
             // If disposing equals true i.e. if disposed explicitly, dispose all 
             // managed resources.
            if (disposing)
            {
             // Dispose managed resources.
            }
             // Clean up unmanaged resources here.
        }
        disposed = true;
      }

      // the below is called the destructor or Finalizer
     ~ClassWithDisposeAndFinalize()
     {
        // Call our shared helper method.
        // Specifying "false" signifies that the GC triggered the cleanup.
        CleanUp(false);
     }

2

Bildiğim en iyi örnek.

 public abstract class DisposableType: IDisposable
  {
    bool disposed = false;

    ~DisposableType()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(false);
      }
    }

    public void Dispose()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(true);
        GC.SuppressFinalize(this);
      }
    }

    public void Close()
    {
      Dispose();
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposing) 
      {
        // managed objects
      }
      // unmanaged objects and resources
    }
  }

2

C # 'da Sonlandırma ve Atma yöntemleri arasındaki fark.

GC, yönetilmeyen kaynakları (dosya işletimi, windows api, ağ bağlantısı, veritabanı bağlantısı gibi) geri almak için sonlandırma yöntemini çağırır, ancak GC bunu çağırdığında zaman sabit değildir. Buna dolaylı olarak GC denir, üzerinde düşük seviye kontrolümüz yoktur.

Atma Yöntemi: Koddan dediğimiz gibi üzerinde düşük seviye kontrolümüz var. kullanılabilir olmadığını düşündüğümüzde yönetilmeyen kaynakları geri alabiliriz.


1

Sınıf örnekleri genellikle çalışma zamanı tarafından yönetilmeyen kaynaklar (pencere tutamaçları (HWND), veritabanı bağlantıları vb.) Üzerindeki denetimi kapsar. Bu nedenle, bu kaynakları boşaltmak için hem açık hem de örtük bir yol sağlamalısınız. Korumalı Sonlandırma Yöntemi'ni bir nesneye (C # 'da yıkıcı sözdizimi ve C ++ için Yönetilen Uzantılar) uygulayarak örtük denetim sağlayın. Çöp toplayıcı, bu nesneye artık geçerli referanslar kalmadığında bir noktada bu yöntemi çağırır. Bazı durumlarda, bir nesne kullanan programcılara, çöp toplayıcı nesneyi serbest bırakmadan önce bu dış kaynakları açıkça serbest bırakma özelliğine sahip olmak isteyebilirsiniz. Harici bir kaynak az veya pahalıysa, programcı artık kullanılmadığında kaynakları açıkça serbest bırakırsa daha iyi performans elde edilebilir. Açık kontrol sağlamak için, IDisposable Interface tarafından sağlanan Dispose yöntemini uygulayın. Nesne tüketicisi, nesne kullanılarak yapıldığında bu yöntemi çağırmalıdır. Nesneye başka referanslar canlı olsa bile imha çağrılabilir.

Dispose yoluyla açık kontrol sağlasanız bile, Finalize yöntemini kullanarak örtük temizleme sağlamanız gerektiğini unutmayın. Sonlandırma, programcı Dispose'i çağırmazsa kaynakların kalıcı olarak sızmasını önlemek için bir yedekleme sağlar.


1

Dispose ve Finalize arasındaki temel fark şudur:

Disposegenellikle kodunuz tarafından çağrılır. Kaynakları aradığınızda anında serbest bırakılır. İnsanlar yöntemi çağırmayı unuturlar, bu yüzden using() {}ifade icat edilir. Programınız içindeki kodun yürütülmesini tamamladığında, yöntemi otomatik olarak {}çağırır Dispose.

Finalizekodunuz tarafından çağrılmamış. Çöp Toplayıcı (GC) tarafından çağrılması kastedilmektedir. Bu, GC'nin buna karar verdiği her zaman kaynağın gelecekte serbest bırakılabileceği anlamına gelir. GC işini yaptığında, birçok Sonlandırma yönteminden geçecektir. Eğer bu konuda ağır bir mantığınız varsa, süreci yavaşlatacaktır. Programınız için performans sorunlarına neden olabilir. Oraya ne koyduğunuza dikkat edin.

İmha mantığının çoğunu kişisel olarak Dispose'e yazardım. Umarım, bu karışıklığı giderir.


-1

Bildiğimiz gibi, imha etme ve sonlandırma her ikisi de yönetilmeyen kaynakları serbest bırakmak için kullanılır .. ancak fark nihai hale getirme kaynakları boşaltmak için iki döngü kullanır, burada dispose olarak bir döngü kullanır ..


Atma kaynağı derhal boşaltır . Kesinleştirme, kaynağı herhangi bir derecede zamanında serbest bırakabilir veya bırakmayabilir.
supercat

1
Ah, muhtemelen bunun "sonlandırılabilir bir nesnenin hafızası geri kazanılmadan önce GC tarafından iki kez algılanması gerektiği" anlamına gelir, daha fazla bilgiyi
aeroson

-4

İlk bölümde cevap vermek için, insanların aynı sınıf nesnesi için farklı yaklaşımlar kullandıkları örnekler vermelisiniz. Aksi takdirde cevap vermek zor (hatta garip).

İkinci soruya gelince daha iyi önce bunu okuyun ıdisposable arabiriminin uygun kullanım hangi iddialar olduğunu

Seçim senin! Ancak İmha Et'i seçin.

Başka bir deyişle: GC sadece finalizörü bilir (eğer varsa. Microsoft'un yıkıcısı olarak da bilinir). İyi bir kod her ikisinden de temizlemeye çalışır (sonlandırıcı ve Atma).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.