2013-06-06 16 views
5

Ben uygulanan sonlandırıcıyı ve yoketme ile "CTransferManaged" adlı bir C++/CLI sınıf var kullanılırsa çağrılmaz Yokedici "CTransfer", CTransferManaged türünde bir m_transfer nesnesi oluşturur.C#/CLI:</p> Bu sınıf, bir C# sınıfı ile sarılır <pre><code>CTransferManaged::~CTransferManaged() { this->!CTransferManaged(); } CTransferManaged::!CTransferManaged() { //Clean up resources... } </code></pre> <p>adlı: Dispose() o

bu sınıfın yıkıcı sadece ben yıkıcı adlı (kesme vurduğunuzda) görebiliriz m_transfer nesnesine başvuru temizler edin:

~CTransfer() 
{ 
    m_transfer = null; //breakpoint on this line 
} 

Ben m_transfer bertaraf edin() işlevini çağırırsanız Başka bir şey değiştirmeden nesne, artık yok denir (kesme noktası daha fazla isabet). Herhangi bir tahmin neden?

~CTransfer() 
{ 
    m_transfer.Dispose(); //breakpoint on this line 
    m_transfer = null; 
} 

ben elle imha çağrı yoksa C++/CLI nesnesi (m_transfer) kaynakları düzgün temizlediğini değil öğrendim elle beri) Dispose (çağırmak istiyorum. Şu anda tam olarak nedenini bilmiyorum.

CTransferManaged :: Dispose() (C++/CLI) çağırır durmaz CTransfer (C# sınıfı) yıkıcısı neden çağrılmaz?

+0

CTransfer sınıfınız *, * m_transfer üyesini uygun şekilde imha edebilmesi için IDisposable kullanmalıdır. Yaptığın gibi görünüyor. ** ** CTransfer için bir finalizer uygulamayın. Bir üyeyi null olarak ayarlamak yararlı bir etkiye sahip değildir ve onun Dispose() yöntemini çağırmak yanlıştır. –

+0

@HansPassant: CTransfer'in sonleştiricisi içinde bir üye nesnenin (m_transfer) Dispose() yöntemini çağırmak neden yanlış? Daha önce de belirttiğim gibi, m_transfer kaynaklarının Dispose() üzerinde aramadığımda düzgün temizlenmediğini öğrendim ( obruend

cevap

0

C# yıkıcı sadece çöp toplayıcı tarafından aranır ve doğrudan arayamazsınız. IDEposalbe arabiriminin bir parçası olan, sadece el ile çağrılmalı ve yıkıcıyı ateşlemeyecek şekilde atılmalıdır.

Yıkıcıya güvenmek yerine, iDisposabe uygulamasını deneyin ve Atma yöntemini doğrudan çağırıp kodunuzu buraya koyun. Kaynak sınıfı imha edilmelidir gömülü nesneler içeriyorsa

, bu desen C# gereklidir:

// C# 
public class Resource : IDisposable 
{ 
    private EmbeddedResource embedded; 

    public Resource() 
    { 
     Console.WriteLine("allocating resource"); 
     embedded = new EmbeddedResource(); 
    } 

    ~Resource() 
    { 
     Dispose(false); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     Console.WriteLine("release resource"); 
     if (disposing) 
     { 
     embedded.Dispose(); 
     } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
    } 
} 
+0

Not: C# nesnesini el ile Dispose() yöntemini (sınıf CTransfer) el ile yapmak istemediğimi unutmayın. Sadece kaynakları m_transfer (sınıf CTransferManaged) manuel bertaraf kullanmak istiyorum çünkü kaynakları düzgün bir şekilde temizlenmiş değil çünkü. – obruend

0

Atılması Sonlandırma Eğer Dispose çağırdığınızda, sonlandırıcı bastırılması gerektiğine şekildedir için tipik desen . Çöken toplayıcı, sınıfı topladığında kaynakları bertaraf etmek için kullanılırken, imha edici, kaynakların bertaraf edilmesini sağlarken, atın her ikisi de aynı şeyi yapmak için tasarlanmıştır (yönetilmeyen kaynakları serbest bırakın). Atmayın, sonlandırıcıyı çağırmak gereksiz ve gereksiz olur ve ayrıca nesnenin toplanmadan ve yok edilmeden önce Finalizer kuyruğuna yerleştirileceğinden dolayı gerekenden daha uzun süre yaşar. Bu, birçok nesnenin oluşturulup bertaraf edildiği yüksek erişilen uygulamalarda zayıf bellek yönetimine neden olur. Bu nedenle, C# en bertaraf yöntemleri arayacak: finalizer yapmamak Çöp toplayıcısı söyler

GC.SuppressFinalize(this); 

. Bu model yaygın olarak kullanılmaktadır ve muhtemelen yönetilmeyen sınıfınızda da kullanılmaktadır. Bu, Dispose çağrısının neden yıkıcıyı elimine ettiğidır.

İlgili konular