SORU
22 Mayıs 2009, Cuma


/C desen Atma sonuçlandırmak#

C# 2008

Bir süredir bunun üzerinde çalışıyorum. Ve hala bazı konularda kafam karıştı. Aşağıda sorularımı

  1. Sen yalnızca yönetilmeyen kaynakları bertaraf eğer bir sonlandırıcı gerektiğini biliyorum. Eğer yönetilen kaynakları kullanıyorsanız ancak, yönetilmeyen kaynakları çağrı yapın. Hala bir sonlandırıcı uygulamak için ihtiyacınız var?

  2. Herhangi bir yönetilmeyen kaynakları doğrudan veya dolaylı olarak kullanmayan bir sınıf geliştirin ve sizin sınıfınızın istemcilerin kullanabilmesi IDisposable uygulamak ancak, 'ifadesi kullanılarak'.

    Sınıf istemcileri kullanarak ifade kullanabilirsiniz IDisposable çok uygulamak için kabul edilebilir mi?

    using(myClass objClass = new myClass())
    {
        // Do stuff here
    }
    
  3. Aşağıda bu basit kod Sonuçlandırmak göstermek/desen elden geliştirdim:

    public class NoGateway : IDisposable
    {
        private WebClient wc = null;
    
        public NoGateway()
        {
            wc = new WebClient();
            wc.DownloadStringCompleted  = wc_DownloadStringCompleted;
        }
    
    
        // Start the Async call to find if NoGateway is true or false
        public void NoGatewayStatus()
        {
            // Start the Async's download
                // Do other work here
            wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
        }
    
        private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            // Do work here
        }
    
        // Dispose of the NoGateway object
        public void Dispose()
        {
            wc.DownloadStringCompleted -= wc_DownloadStringCompleted;
            wc.Dispose();
            GC.SuppressFinalize(this);
        }
    }
    

Kaynak kod: hakkında bir soru

  1. Burada sonlandırıcı ekledim. Ve normalde sonlandırıcı GC tarafından çağrılır, ve sonlandırıcı iş Atma arayacak. Sonlandırıcı yok gibi, ne zaman Atma yöntemi arayayım mı? Buna sahip sınıf müşteri mi?

    Örneğin benim sınıf NoGateway denir ve istemci kullanın ve bu gibi sınıf atmayın diye

    using(NoGateway objNoGateway = new NoGateway())
    {
        // Do stuff here   
    }
    

    Bu yöntemi kullanarak yürütme bloğunun sonuna ulaştığında otomatik olarak adlandırılır ateşe atar? Veya istemci el ile atma yöntemini yani aramak zorunda mı?

    NoGateway objNoGateway = new NoGateway();
    // Do stuff with object
    objNoGateway.Dispose(); // finished with it
    
  2. NoGateway sınıfımdaki webclient sınıfını kullanıyorum. Webclient IDisposable arabirimini uygular. Bu, Professional (Service dolaylı olarak yönetilmeyen kaynakları kullanan anlamına mı geliyor? Sert ve hızlı bir kural bu konuyu takip etmektir. Nasıl bir sınıf yönetilmeyen kaynakları kullanır.

CEVAP
22 Mayıs 2009, Cuma


Tavsiye IDisposable desen here. IDisposable kullanan bir sınıf programlarken, genellikle iki desenleri kullanmanız gerekir:

Yönetilmeyen kaynakları kullanmayan mühürlü bir sınıf uygularken, sadece normal bir arayüz uygulamaları ile ilgili olarak Atma yöntemi uygulayın:

public sealed class A : IDisposable
{
    public void Dispose()
    {
        // get rid of managed resources, call Dispose on member variables...
    }
}

Mühürsüz bir sınıf uygularken, bu gibi yapın:

public class B : IDisposable
{    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // get rid of managed resources
        }   
        // get rid of unmanaged resources
    }

    // only if you use unmanaged resources directly in B
    //~B()
    //{
    //    Dispose(false);
    //}
}

Almadım dikkat edin B; yalnızca elden gerçek yönetilmeyen kaynakları varsa bir sonlandırıcı uygulamak bir sonlandırıcı ilan etti. CLR SuppressFinalize çağrılırsa bile finalizable nesneleri olmayan finalizable nesnelere farklı ile ilgilenir.

Yani, olmamalı ilan bir sonlandırıcı sürece senin için, ama sen ver mirasçıların sınıf bir kanca için çağrı Dispose ve uygulamak bir sonlandırıcı kendilerini kullandıkları yönetilmeyen kaynakları doğrudan:

public class C : B
{
    private IntPtr m_Handle;

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // get rid of managed resources
        }
        ReleaseHandle(m_Handle);

        base.Dispose(disposing);
    }

    ~C() {
        Dispose(false);
    }
}

Değilsen kullanarak yönetilmeyen kaynakları doğrudan (SafeHandle ve arkadaş sayılmaz, beyan ederim kendi sonlandırıcı), sonra da yok hayata bir sonlandırıcı, GC fırsatları ile finalizable sınıflar farklı olsa bile, daha sonra bastırmak sonlandırıcısı. Ayrıca, B bir sonlandırıcı yok olsa bile, yine de SuppressFinalize düzgün bir sonlandırıcı uygulayan herhangi bir alt ile başa çıkmak için çağırır.

Bir sınıf IDisposable arabirimini uygular, bir sınıf kullanmayı bitirdikten sonra kurtuldum edilmesi gereken bazı yönetilmeyen kaynakları var demektir. Gerçek kaynaklar sınıfları içinde saklanmış; açıkça onları silmek gerek yok. Sadece Dispose() arama using(...) {} a sınıfı sarma yönetilmeyen kaynakları kurtulmak gerekli olarak var olan herhangi bir emin olun.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • AlaskanGrizzly

    AlaskanGrizz

    30 EKİM 2009
  • hoorahjencar

    hoorahjencar

    6 HAZİRAN 2007
  • Lin Steven

    Lin Steven

    17 EKİM 2006