Dışarıya aktar (0) Yazdır
Tümünü Genişlet
Bu makale makine tarafından çevrilmiştir. Orijinal metni görmek için imlecinizi makaledeki cümlelerin üzerine getirin. Daha Fazla Bilgi.
Çeviri
Original

Object.Finalize Yöntem

Atık toplama işlemi tarafından alınmadan önce nesnenin kaynaklarını boşaltmayı denemesine izin verir.

Ad alanı:  System
Derleme:  mscorlib (mscorlib.dll içinde)

protected virtual void Finalize()

Finalize Yöntemi nesne yok edilmeden geçerli nesne tarafından tutulan yönetilmeyen kaynakları temizleme işlemleri için kullanılır. Yöntem korumalı ve bu nedenle yalnızca bu sınıf veya türetilmiş bir sınıf aracılığıyla erişilebilir.

Bu bölümde:

Sonlandırma nasıl çalışır?

Object Sınıfı uygulaması sağlar Finalize yöntemi ve çöp toplayıcı işaretlediğiniz türetilen türler Object sonlandırılması için bunlar yazmadığınız sürece Finalize yöntem.

Bir tür geçersiz kılarsanız Finalize yöntemi, çöp toplayıcı ekler türünün her örneği için bir girdi sonlandırma sırası adı verilen bir iç yapısı. Sonlandırma sırası kendi bellek çöp toplayıcısı kazandıracaktır önce sonlandırma kodu çalıştırmanız gerekir yönetilen yığında bulunan tüm nesneler için girişleri içerir. Daha sonra çöp toplayıcı çağırır Finalize otomatik olarak aşağıdaki koşullarda yöntemi:

  • Bir nesnenin nesne sonlandırma bir çağrı tarafından bırakılan olmadıkça erişilemez, olduktan sonra GC.SuppressFinalize yöntem.

  • Bir uygulama etki alanının kapatma sırasında nesne sonlandırma muaf olmadığı sürece. Kapatma sırasında bile hala erişilebilir nesneleri olan sonlandırılır.

Finalize Nesne bir mekanizma kullanılarak yeniden kaydedilmiş sürece otomatik olarak yalnızca bir kez belirli bir örneğinde denir GC.ReRegisterForFinalize ve GC.SuppressFinalize yöntemi sonradan çağrılmadı.

Finalize işlemleri aşağıdaki sınırlamalara sahiptir:

  • Ne zaman sonlandırıcıyı çöp toplama sırasında tam çalýþtýrdýðýnda, tanımlı değil. Sınıfın örneklerini uygulamak için kararlı sürümü kaynaklar sağlamak için bir Close yöntemini veya sağladığınız bir IDisposable.Dispose uygulaması.

  • Bir nesne için diğer bile başvuruyorsa sonlandırıcılar iki nesne belirli bir sırada çalıştırılacak garanti edilmez. A nesnesinin sonlandırıcıyı başladığında, diğer bir deyişle, nesne B başvuru nesnesi A sahiptir ve her ikisi de sonlandırıcılar varsa, nesne B zaten sonuna.

  • Sonlandırıcı çalıştığı iş parçacığı belirtilmemiş.

Finalize Yöntemi tamamlama için çalışmayabilir veya hiç şu olağanüstü koşullarda çalışmayabilir:

  • Başka bir sonlandırıcı sonsuza kadar engelliyorsa, (sonsuz bir döngü gerçekleştirip gerçekleştirmeyeceğini çalışır hiçbir zaman elde ve benzeri bir kilit elde edilir). Sonlandırıcılar tamamlanması için çalıştırmak çalışma zamanında çalışır çünkü diğer sonlandırıcılar sonlandırıcıyı blokları, süresiz olarak adlandırılabilir değil.

  • Çalışma zamanı temizlemek için bir şans vermeden işlemi sona ererse. Bu durumda, çalışma zamanı'nın ilk bildirim işlemi sonlandırma DLL_PROCESS_DETACH bildirimdir.

Çalışma zamanı yalnızca sonlandırılabilir nesnelerin sayısını azaltmak devam ederken nesneleri kapatma sırasında sonlandırmaya devam eder.

Yoksa Finalize veya geçersiz kılma Finalize bir özel durum atar ve çalışma zamanı varsayılan ilke geçersiz kılan bir uygulama tarafından barındırılan değil, işlem ve hiçbir etkin çalışma zamanının sona erer try/finally blokları veya sonlandırıcılar çalıştırılır. Bu davranış sonlandırıcıyı boşaltın veya kaynaklar yok, işlem tutarlılığı sağlar.

Uygulayıcılar için Notlar

Geçersiz kılmanız Finalize gibi yönetilmeyen kaynakları kullanan bir sınıf için dosya tanıtıcıları veya veritabanı bağlantısını onları kullanan yönetilen nesneyi çöp toplama işlemi sırasında atılır, serbest bırakılması gerekir.

Önemli notÖnemli

Yoksa bir SafeHandle nesnesi kullanılabilir, yönetilmeyen kaynağınızın sarar, önerilen alternatif güvenli tanıtıcı dispose deseni uygulamak ve geçersiz olduğunu Finalize. Daha fazla bilgi için bkz: SafeHandle alternatif bölüm.

Object.Finalize Yöntemi varsayılan olarak yapmaz ancak, geçersiz Finalize yalnızca gerekli ve yalnızca yönetilmeyen kaynakları serbest bırakmak için. Atık toplama sırasında bellek reclaiming en az iki atık toplama işlemleri gerektirdiğinden sonlandırma işlemi çalışıyorsa, daha uzun sürer eğilimindedir. Ayrıca, geçersiz kılmanız Finalize türleri yalnızca başvuru için yöntem. Ortak dil çalışma zamanı yalnızca başvuru türleri böylece. Değer türleri üzerinde sonlandırıcılar yoksayar.

Her uygulama, Finalize türetilmiş bir tür kendi taban türü olarak çağırmalı Finalize. Bu uygulama kodu izin verilen çağırmak için yalnızca geçerli Finalize.

NotNot

C# derleyicisi geçersiz kılmak izin vermiyor Finalize yöntem. Bunun yerine, uygulama tarafından bir sonlandırıcı sağlayan bir yıkıcı sınıfınız için. Bir C# yıkıcı otomatik olarak kendi temel sınıf yıkıcısını.

Visual C++ da uygulamak için kendi sözdizimi sağlar Finalize yöntem. Daha fazla bilgi için "Yıkıcı ve sonlandırıcılar" bölümüne bakın Nasıl yapılır: sınıflar ve yapılar örneğini oluşturma.

Atık toplama kararlı olmayan olduğundan, tam olarak çöp toplayıcı sonlandırma gerçekleştirdiğinde, bilinmemektedir. Kaynakları serbest bırakmak için hemen de uygulamak seçebilirsiniz Desen elden ve IDisposable arabirim. IDisposable.Dispose Uygulama yönetilmeyen kaynakları serbest tüketicilerin sınıfınızın tarafından çağrılabilir ve kullanabilirsiniz Finalize yöntem yönetilmeyen kaynakları boşaltmak için durumunda Dispose yöntemi çağrılmaz.

Finalize atık toplama sırasında temizlendi sonra (nesneyi erişilebilir yeniden yapıyor) bir nesne başvurularından da dahil olmak üzere hemen hemen tüm, önlem alabilirsiniz. Ancak, nesne yalnızca bir kez yeniden etkinleştirilen; Finalizeyeniden etkinleştirilen nesnelerde çöp toplama sırasında çağrılamaz. Bir eylem, uygulamanız, Finalize hiçbir zaman sürer: hiçbir zaman özel durum oluşturması gerekir.

SafeHandle alternatifi

Güvenilir sonlandırıcılar oluşturma genellikle zor, uygulama durumu hakkında varsayımlar yapamazsınız çünkü ve sistem gibi işlenmemiş çünkü OutOfMemoryException ve StackOverflowException sonlandırıcıyı sonlandırın. Yönetilmeyen kaynakları serbest bırakmak için kullanacağınız sınıf için bir sonlandırıcı uygulamak yerine, türetilmiş bir nesne kullanabilirsiniz System.Runtime.InteropServices.SafeHandle , yönetilmeyen kaynakları kaydırmak için sınıf ve ardından bir sonlandırıcı olmadan dispose desenini uygular. .NET Framework içinde aşağıdaki sınıflar sağlar Microsoft.Win32 türetilmiştir ad System.Runtime.InteropServices.SafeHandle:

Aşağıdaki örnek Desen elden geçersiz kılma yerine güvenli tutamaçlı Finalize yöntem. Onu tanımlayan bir FileAssociation kayıt defteri bilgileri hakkında belirli bir uzantıya sahip dosyaları işleyen uygulama saran bir sınıf. Olarak döndürülen iki kayıt defteri tanıtıcıları out parametreleri Windows tarafından RegOpenKeyEx işlev çağrıları için geçirilir SafeRegistryHandle kurucusu. Tür korunan Dispose sonra yöntemi çağırır SafeRegistryHandle.Dispose bu iki tutamaçları boşaltmak için yöntem.


using Microsoft.Win32.SafeHandles;
using System;
using System.ComponentModel;
using System.IO;
using System.Runtime.InteropServices;

public class FileAssociationInfo : IDisposable
{
   // Private variables.
   private String ext;
   private String openCmd;
   private String args;
   private SafeRegistryHandle hExtHandle, hAppIdHandle;

   // Windows API calls.
   [DllImport("advapi32.dll", CharSet= CharSet.Auto, SetLastError=true)]
   private static extern int RegOpenKeyEx(IntPtr hKey, 
                  String lpSubKey, int ulOptions, int samDesired,
                  out IntPtr phkResult);
   [DllImport("advapi32.dll", CharSet= CharSet.Unicode, EntryPoint = "RegQueryValueExW",
              SetLastError=true)]
   private static extern int RegQueryValueEx(IntPtr hKey,
                  string lpValueName, int lpReserved, out uint lpType, 
                  string lpData, ref uint lpcbData);   
   [DllImport("advapi32.dll", SetLastError = true)]
   private static extern int RegSetValueEx(IntPtr hKey, [MarshalAs(UnmanagedType.LPStr)] string lpValueName,
                  int Reserved, uint dwType, [MarshalAs(UnmanagedType.LPStr)] string lpData,
                  int cpData);
   [DllImport("advapi32.dll", SetLastError=true)]
   private static extern int RegCloseKey(UIntPtr hKey);

   // Windows API constants.
   private const int HKEY_CLASSES_ROOT = unchecked((int) 0x80000000);
   private const int ERROR_SUCCESS = 0;

    private const int KEY_QUERY_VALUE = 1;
    private const int KEY_SET_VALUE = 0x2;

   private const uint REG_SZ = 1;

   private const int MAX_PATH = 260;

   public FileAssociationInfo(String fileExtension)
   {
      int retVal = 0;
      uint lpType = 0;

      if (!fileExtension.StartsWith("."))
             fileExtension = "." + fileExtension;
      ext = fileExtension;

      IntPtr hExtension = IntPtr.Zero;
      // Get the file extension value.
      retVal = RegOpenKeyEx(new IntPtr(HKEY_CLASSES_ROOT), fileExtension, 0, KEY_QUERY_VALUE, out hExtension);
      if (retVal != ERROR_SUCCESS) 
         throw new Win32Exception(retVal);
      // Instantiate the first SafeRegistryHandle.
      hExtHandle = new SafeRegistryHandle(hExtension, true);

      string appId = new string(' ', MAX_PATH);
      uint appIdLength = (uint) appId.Length;
      retVal = RegQueryValueEx(hExtHandle.DangerousGetHandle(), String.Empty, 0, out lpType, appId, ref appIdLength);
      if (retVal != ERROR_SUCCESS)
         throw new Win32Exception(retVal);
      // We no longer need the hExtension handle.
      hExtHandle.Dispose();

      // Determine the number of characters without the terminating null.
      appId = appId.Substring(0, (int) appIdLength / 2 - 1) + @"\shell\open\Command";

      // Open the application identifier key.
      string exeName = new string(' ', MAX_PATH);
      uint exeNameLength = (uint) exeName.Length;
      IntPtr hAppId;
      retVal = RegOpenKeyEx(new IntPtr(HKEY_CLASSES_ROOT), appId, 0, KEY_QUERY_VALUE | KEY_SET_VALUE,
                            out hAppId);
       if (retVal != ERROR_SUCCESS) 
         throw new Win32Exception(retVal);

      // Instantiate the second SafeRegistryHandle.
      hAppIdHandle = new SafeRegistryHandle(hAppId, true);

      // Get the executable name for this file type.
      string exePath = new string(' ', MAX_PATH);
      uint exePathLength = (uint) exePath.Length;
      retVal = RegQueryValueEx(hAppIdHandle.DangerousGetHandle(), String.Empty, 0, out lpType, exePath, ref exePathLength);
      if (retVal != ERROR_SUCCESS)
         throw new Win32Exception(retVal);

      // Determine the number of characters without the terminating null.
      exePath = exePath.Substring(0, (int) exePathLength / 2 - 1);
      // Remove any environment strings.
      exePath = Environment.ExpandEnvironmentVariables(exePath);

      int position = exePath.IndexOf('%');
      if (position >= 0) {
         args = exePath.Substring(position);
         // Remove command line parameters ('%0', etc.).
         exePath = exePath.Substring(0, position).Trim();
      }
      openCmd = exePath;   
   }

   public String Extension
   { get { return ext; } }

   public String Open
   { get { return openCmd; } 
     set {
        if (hAppIdHandle.IsInvalid | hAppIdHandle.IsClosed)
           throw new InvalidOperationException("Cannot write to registry key."); 
        if (! File.Exists(value)) {
           string message = String.Format("'{0}' does not exist", value);
           throw new FileNotFoundException(message); 
        }
        string cmd = value + " %1";
        int retVal = RegSetValueEx(hAppIdHandle.DangerousGetHandle(), String.Empty, 0, 
                                   REG_SZ, value, value.Length + 1);
        if (retVal != ERROR_SUCCESS)
           throw new Win32Exception(retVal);                          
     } }

   public void Dispose() 
   {
      Dispose(true);
      GC.SuppressFinalize(this);
   }   

   protected void Dispose(bool disposing)
   {
      // Ordinarily, we release unmanaged resources here; 
      // but all are wrapped by safe handles.

      // Release disposable objects.
      if (disposing) {
         if (hExtHandle != null) hExtHandle.Dispose();
         if (hAppIdHandle != null) hAppIdHandle.Dispose();
      }
   }
}


Aşağıdaki örnek, doğrular Finalize yöntemi çağrıldığında, bir nesne geçersiz kıldığında Finalize yok. Bir üretim uygulamasında dikkat edin Finalize yöntemi geçersiz kılınmış nesne tarafından tutulan yönetilmeyen kaynakları serbest bırakmak için. Ayrıca C# örnek geçersiz kılma yerine bir yıkıcı unutmayın Finalize yöntem.


using System;
using System.Diagnostics;

public class ExampleClass
{
   Stopwatch sw;

   public ExampleClass()
   {
      sw = Stopwatch.StartNew();
      Console.WriteLine("Instantiated object");
   } 

   public void ShowDuration()
   {
      Console.WriteLine("This instance of {0} has been in existence for {1}",
                        this, sw.Elapsed);
   }

   ~ExampleClass()
   {
      Console.WriteLine("Finalizing object");
      sw.Stop();
      Console.WriteLine("This instance of {0} has been in existence for {1}",
                        this, sw.Elapsed);
   }
}

public class Demo
{
   public static void Main()
   {
      ExampleClass ex = new ExampleClass();
      ex.ShowDuration();
   }
}
// The example displays output like the following:
//    Instantiated object
//    This instance of ExampleClass has been in existence for 00:00:00.0011060
//    Finalizing object
//    This instance of ExampleClass has been in existence for 00:00:00.0036294


Geçersiz kılan bir başka örnek Finalize yöntemi, bkz: GC.SuppressFinalize yöntem.

.NET Framework

Destekleyen: 4.5.2, 4.5.1, 4.5, 4, 3.5, 3.0, 2.0, 1.1, 1.0

.NET Framework İstemci Profili

Destekleyen: 4, 3.5 SP1

Taşınabilir Sınıf Kitaplığı

Destekleyen: Taşınabilir Sınıf Kitaplığı

Windows Mağazası uygulamaları için .NET

Destekleyen: Windows 8

Windows Phone uygulamaları için .NET

Destekleyen: Windows Phone 8, Silverlight 8.1

Windows Phone 8.1, Windows Phone 8, Windows 8.1, Windows Server 2012 R2, Windows 8, Windows Server 2012, Windows 7, Windows Vista SP2, Windows Server 2008 (Sunucu Çekirdeği Rolü desteklenmez), Windows Server 2008 R2 (Sunucu Çekirdeği Rolü, SP1 veya sonraki sürümlerle desteklenir; Itanium'da desteklenmez)

.NET Framework her platformun tüm sürümlerini desteklemez. Desteklenen sürümlerin listesi için bkz. .NET Framework Sistem Gereksinimleri.

Topluluk İçeriği

Ekle
Show:
© 2014 Microsoft