Bu makale, makine tarafından çevrilmiştir. Makaleyi İngilizce dilinde görüntülemek için İngilizce onay kutusunu işaretleyin. Ayrıca, fare işaretçisiyle İngilizce metnin üzerine gelerek metni açılır pencerede de görüntüleyebilirsiniz.
Çeviri
İngilizce

Object.Finalize Yöntemi ()

 

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 önce geçerli nesne tarafından tutulan yönetilmeyen kaynakları temizleme işlemleri için kullanılır. Yöntem korunur ve bu nedenle yalnızca bu sınıf veya türetilmiş bir sınıf üzerinden erişilebilir.

Bu bölümde:

Object Sınıfı sağlar uygulaması Finalize yöntemi ve atık toplayıcı işaretlediğiniz türetilmiş türleri Object sonlandırma için bunlar geçersiz kılar sürece Finalize yöntemi.

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 giriş sonlandırma yapısı adı verilen bir iç yapı. Sonlandırma sırası, çöp toplayıcının bellekten kaldırması için önce sonlandırma kodu çalıştırmanız gerekir yönetilen Yığındaki tüm nesneler için girişleri içerir. Atık toplayıcı ardından çağırır Finalize yöntemi aşağıdaki koşullar altında otomatik olarak:

  • Atık toplayıcı nesne için bir çağrı tarafından sonlandırma bırakılan sürece bir nesne erişilemez, bulunan sonra GC.SuppressFinalize yöntemi.

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

Finalize nesne gibi bir mekanizma kullanılarak yeniden kaydedilmemişse otomatik olarak yalnızca bir kez bir verilen örneği üzerinde çağrılır GC.ReRegisterForFinalize ve GC.SuppressFinalize yöntemi daha sonra çağrılmadı.

Finalize işlem aşağıdaki sınırlamaları vardır:

  • Ne zaman Sonlandırıcı yürütür tam zaman tanımsızdır. Sınıfın örnekleri uygulamak için kaynakların belirli şekilde serbest emin olmak için bir Close yöntemi veya sağlayan bir IDisposable.Dispose uygulaması.

  • Bir nesne için diğer başvurur olsa bile sonlandırıcılar iki nesne belirli bir sırayla çalıştırmak için garanti edilmez. Bir nesnenin Sonlandırıcısı başlatıldığında, diğer bir deyişle, nesne bir nesne B bir başvuru içeriyor ve her ikisi de sonlandırıcılar varsa, nesne B zaten sonuna.

  • İş parçacığı Sonlandırıcı çalıştığı belirtilmedi.

Finalize Yöntemi tamamlanıncaya kadar çalışmayabilir veya olağanüstü şu koşullarda hiç çalışmayabilir:

  • Başka bir sonlandırıcı süresiz olarak engelliyorsa, (sonsuz bir döngü gerçekleştirmeyeceğini çalışır hiçbir zaman elde ve benzeri bir kilidi almak). Çalışma zamanı sonlandırıcılar tamamlanmak üzere çalıştırılmasını çalıştığı için diğer sonlandırıcılar Sonlandırıcı blokları, süresiz olarak çağrılmaması.

  • Çalışma zamanı temizlemek için bir fırsat vermeden işlemi sonlandıran gerekiyorsa. Bu durumda, çalışma zamanının ilk bildirim işlemi sonlandırma DLL_PROCESS_DETACH bildirimidir.

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

Varsa Finalize veya geçersiz kılma Finalize bir özel durumu oluşturur ve çalışma zamanı varsayılan ilkeyi geçersiz kılan bir uygulama tarafından barındırılan değil, çalışma zamanı işlemi ve hiçbir etkin sonlandırır try/finally blokları veya sonlandırıcılar çalıştırılır. Bu davranış, sonlandırıcı boş veya kaynakları destroy işlem bütünlüğü sağlar.

Geçersiz kılmalısınız Finalize gibi yönetilmeyen kaynakları kullanan bir sınıf için dosya tanıtıcıları veya veritabanı bağlantılarını bunları kullanan Yönetilen Nesne çöp toplama sırasında iptal edilir, serbest bırakılması gerekir.

System_CAPS_importantÖnemli

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

Object.Finalize Yöntemi yapmaz varsayılan olarak, ancak geçersiz kılmalısınız Finalize yalnızca gerekli ve yalnızca yönetilmeyen kaynakları serbest bırakmak. Belleği geri kazanmak en az iki çöp toplama gerektirdiğinden bir sonlandırma işlemi çalıştırıyorsa, daha uzun sürer eğilimi gösterir. Ayrıca, geçersiz kılmalısınız Finalize türleri yalnızca başvuru için yöntemi. Ortak dil çalışma zamanı yalnızca başvuru türleri sonlandırır. Değer türleri üzerinde sonlandırıcılar göz ardı eder.

Her uygulanması Finalize türetilen türde de kendi temel türün, çağırmalı Finalize. Bu uygulama kod çağırmak için verilir yalnızca durumda Finalize.

System_CAPS_noteNot

C# derleyicisi, geçersiz kılmak izin vermiyor Finalize yöntemi. Bunun yerine, bir sonlandırıcı uygulayarak sağladığınız bir yıkıcı sınıfınız için. Bir C# yok edici temel sınıfındaki yıkıcı otomatik olarak çağırır.

Visual C++ da uygulamak için kendi sözdizimini sağlar Finalize yöntemi. Daha fazla bilgi için "Yok ediciler ve sonlandırıcılar" bölümüne bakın Nasıl yapılır: sınıfları ve yapıları (C++ CLI) tanımlama ve kullanma.

Çöp toplama belirleyici olduğundan, tam olarak çöp toplayıcı sonlandırma gerçekleştirdiğinde, bilmediğiniz. Kaynakları serbest bırakmak için hemen ayrıca uygulamak seçebilirsiniz dispose deseni ve IDisposable arabirimi. IDisposable.Dispose Uygulaması yönetilmeyen kaynakları serbest bırakmak tüketiciler sınıfınızın tarafından çağrılabilir ve kullanabileceğiniz Finalize yöntemi yönetilmeyen kaynakları serbest bırakmak durumunda Dispose yöntemi çağrılmaz.

Finalize Çöp toplama sırasında temizlendi sonra (nesne erişilebilir yeniden yapmak için olan) bir nesne başvurularından da dahil olmak üzere, neredeyse tüm işlemleri gerçekleştirebilir. Ancak, nesne yalnızca bir kez yeniden etkinleştirilen; Finalize yeniden etkinleştirilen nesnelerde çöp toplama sırasında çağrılamaz. Bir eylem yoktur, uygulamanıza Finalize hiçbir zaman katmalıdır: hiçbir zaman özel bir durum oluşturmamalıdır.

Güvenilir sonlandırıcılar oluşturma genellikle zor, uygulamanızın durumunu varsayımlar yapılamıyor çünkü ve sistem gibi işlenmemiş olduğundan OutOfMemoryException ve StackOverflowException Sonlandırıcı sonlandırın. Yönetilmeyen kaynakları serbest bırakmak sınıfınız için bir sonlandırıcı uygulamak yerine, türetilmiş bir nesne kullanabilirsiniz System.Runtime.InteropServices.SafeHandle sınıfının yönetilmeyen kaynaklarınızı saran ve ardından bir sonlandırıcı olmadan dispose deseni uygulamak. .NET Framework aşağıdaki sınıfları sağlar Microsoft.Win32 türetilmiştir ad alanı System.Runtime.InteropServices.SafeHandle:

Aşağıdaki örnek, kullanır dispose deseni geçersiz kılma yerine güvenli tanıtıcılar ile Finalize yöntemi. Tanımlayan bir FileAssociation belirli dosya uzantılı dosyaları işleyen uygulamayla ilgili kayıt defteri bilgileri saran bir sınıf. Olarak döndürülen iki kayıt defteri tanıtıcıları out Windows parametrelerin RegOpenKeyEx öğesine geçirilen işlev çağrıları SafeRegistryHandle Oluşturucusu. Türü korumalı Dispose sonra yöntemi çağırır SafeRegistryHandle.Dispose Bu iki tutamaçları boşaltmak için yöntemi.

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 edilir. Bir üretim uygulamasında dikkat edin Finalize yöntemi geçersiz nesne tarafından tutulan yönetilmeyen kaynakları serbest bırakmak için. Ayrıca C# örneği geçersiz kılma yerine bir yok edici sağladığını unutmayın Finalize yöntemi.

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

For an additional example that overrides the M:System.Object.Finalize method, see the M:System.GC.SuppressFinalize(System.Object) method.

Evrensel Windows Platformu
8 sonrasında kullanılabilir
.NET Framework
1.1 sonrasında kullanılabilir
Taşınabilir Sınıf Kitaplığı
Destekleyen: taşınabilir .NET platformları
Silverlight
2.0 sonrasında kullanılabilir
Windows Phone Silverlight
7.0 sonrasında kullanılabilir
Windows Phone
8.1 sonrasında kullanılabilir
Başa dön
Show: