Бөлісу құралы:


GC.WaitForPendingFinalizers Метод

Определение

Приостанавливает текущий поток до тех пор, пока поток, обрабатывающий очередь методов завершения, не обработает всю очередь.

public:
 static void WaitForPendingFinalizers();
public static void WaitForPendingFinalizers ();
static member WaitForPendingFinalizers : unit -> unit
Public Shared Sub WaitForPendingFinalizers ()

Примеры

В следующем примере показано, как использовать WaitForPendingFinalizers метод для приостановки текущего потока до завершения завершения всех собранных объектов.

using namespace System;
ref class MyFinalizeObject
{
private:

   // Make this number very large to cause the finalizer to
   // do more work.
   literal int maxIterations = 10000;
   ~MyFinalizeObject()
   {
      Console::WriteLine( "Finalizing a MyFinalizeObject" );
      
      // Do some work.
      for ( int i = 0; i < maxIterations; i++ )
      {
         
         // This method performs no operation on i, but prevents
         // the JIT compiler from optimizing away the code inside
         // the loop.
         GC::KeepAlive( i );

      }
   }

};


// You can increase this number to fill up more memory.
const int numMfos = 1000;

// You can increase this number to cause more
// post-finalization work to be done.
const int maxIterations = 100;
int main()
{
   MyFinalizeObject^ mfo = nullptr;
   
   // Create and release a large number of objects
   // that require finalization.
   for ( int j = 0; j < numMfos; j++ )
   {
      mfo = gcnew MyFinalizeObject;

   }
   
   //Release the last object created in the loop.
   mfo = nullptr;
   
   //Force garbage collection.
   GC::Collect();
   
   // Wait for all finalizers to complete before continuing.
   // Without this call to GC::WaitForPendingFinalizers,
   // the worker loop below might execute at the same time
   // as the finalizers.
   // With this call, the worker loop executes only after
   // all finalizers have been called.
   GC::WaitForPendingFinalizers();
   
   // Worker loop to perform post-finalization code.
   for ( int i = 0; i < maxIterations; i++ )
   {
      Console::WriteLine( "Doing some post-finalize work" );

   }
}
using System;

namespace WaitForPendingFinalizersExample
{
   class MyWaitForPendingFinalizersClass
   {
    // You can increase this number to fill up more memory.
    const int numMfos = 1000;
    // You can increase this number to cause more
    // post-finalization work to be done.
    const int maxIterations = 100;

    static void Main(string[] args)
    {
       MyFinalizeObject mfo = null;

       // Create and release a large number of objects
       // that require finalization.
       for(int j = 0; j < numMfos; j++)
       {
          mfo = new MyFinalizeObject();
       }

       //Release the last object created in the loop.
       mfo = null;

       //Force garbage collection.
       GC.Collect();

       // Wait for all finalizers to complete before continuing.
       // Without this call to GC.WaitForPendingFinalizers,
       // the worker loop below might execute at the same time
       // as the finalizers.
       // With this call, the worker loop executes only after
       // all finalizers have been called.
       GC.WaitForPendingFinalizers();

       // Worker loop to perform post-finalization code.
       for(int i = 0; i < maxIterations; i++)
       {
          Console.WriteLine("Doing some post-finalize work");
       }
    }
   }

   class MyFinalizeObject
   {
    // Make this number very large to cause the finalizer to
    // do more work.
    private const int maxIterations = 10000;

    ~MyFinalizeObject()
    {
       Console.WriteLine("Finalizing a MyFinalizeObject");
            
       // Do some work.
       for(int i = 0; i < maxIterations; i++)
       {
          // This method performs no operation on i, but prevents
          // the JIT compiler from optimizing away the code inside
          // the loop.
          GC.KeepAlive(i);
       }
        }
    }
}
open System

// You can increase this number to fill up more memory.
let numMfos = 1000

// You can increase this number to cause more
// post-finalization work to be done.
let maxIterations = 100

[<AllowNullLiteral>]
type MyFinalizeObject() =
    // Make this number very large to cause the finalizer todo more work.
    let maxIterations = 10000

    override _.Finalize() =
        printfn "Finalizing a MyFinalizeObject"
        
        // Do some work.
        for i = 1 to maxIterations do
            // This method performs no operation on i, but prevents
            // the JIT compiler from optimizing away the code inside
            // the loop.
            GC.KeepAlive i

let mutable mfo = null

// Create and release a large number of objects
// that require finalization.
for j = 1 to numMfos do
    mfo <- MyFinalizeObject()

//Release the last object created in the loop.
mfo <- null

//Force garbage collection.
GC.Collect()

// Wait for all finalizers to complete before continuing.
// Without this call to GC.WaitForPendingFinalizers,
// the worker loop below might execute at the same time
// as the finalizers.
// With this call, the worker loop executes only after
// all finalizers have been called.
GC.WaitForPendingFinalizers()

// Worker loop to perform post-finalization code.
for _ = 1 to maxIterations do
    printfn "Doing some post-finalize work"
Namespace WaitForPendingFinalizersExample
   Class MyWaitForPendingFinalizersClass
  
    ' You can increase this number to fill up more memory.
      Private Const numMfos As Integer = 1000
      ' You can increase this number to cause more
      ' post-finalization work to be done.
      Private Const maxIterations As Integer = 100
     
      Overloads Shared Sub Main()
         Dim mfo As MyFinalizeObject = Nothing
      
         ' Create and release a large number of objects
         ' that require finalization.
         Dim j As Integer
         For j = 0 To numMfos - 1
            mfo = New MyFinalizeObject()
         Next j
      
         'Release the last object created in the loop.
         mfo = Nothing
      
         'Force garbage collection.
         GC.Collect()
      
         ' Wait for all finalizers to complete before continuing.
         ' Without this call to GC.WaitForPendingFinalizers, 
         ' the worker loop below might execute at the same time 
         ' as the finalizers.
         ' With this call, the worker loop executes only after
         ' all finalizers have been called.
         GC.WaitForPendingFinalizers()
      
         ' Worker loop to perform post-finalization code.
         Dim i As Integer
         For i = 0 To maxIterations - 1
            Console.WriteLine("Doing some post-finalize work")
         Next i
      End Sub
   End Class


   Class MyFinalizeObject
      ' Make this number very large to cause the finalizer to
      ' do more work.
      Private maxIterations As Integer = 10000
      
      Protected Overrides Sub Finalize()
         Console.WriteLine("Finalizing a MyFinalizeObject")
      
         ' Do some work.
         Dim i As Integer
         For i = 0 To maxIterations - 1
            ' This method performs no operation on i, but prevents 
            ' the JIT compiler from optimizing away the code inside 
            ' the loop.
            GC.KeepAlive(i)
         Next i
         MyBase.Finalize()
      End Sub
   End Class
End Namespace

Комментарии

Когда сборщик мусора находит объекты, которые могут быть освобождены, он проверяет каждый объект, чтобы определить требования к завершению объекта. Если объект реализует метод завершения и не отключает завершение путем вызова SuppressFinalize, объект помещается в список объектов, помеченных как готовые к завершению. Сборщик мусора вызывает Finalize методы для объектов в этом списке и удаляет записи из списка. Этот метод блокируется до тех пор, пока все методы завершения не будут завершены.

Поток, в котором выполняются методы завершения, не указан, поэтому не гарантируется, что этот метод завершит работу. Однако этот поток может быть прерван другим потоком во время WaitForPendingFinalizers выполнения метода. Например, можно запустить другой поток, который ожидает некоторое время, а затем прерывает этот поток, если этот поток по-прежнему приостановлен.

Применяется к