C# 託管資源與非託管資源(參考七)
阿新 • • 發佈:2020-04-20
本文轉自:https://docs.microsoft.com/zh-cn/dotnet/api/system.gc.suppressfinalize?redirectedfrom=MSDN&view=netframework-4.8#System_GC_SuppressFinalize_System_Object_
請求公共語言執行時不要呼叫指定物件的終結器。
C#public static void SuppressFinalize (object obj);
引數
- obj
- Object
不得執行其終結器的物件。
例外
ArgumentNullExceptionobj
為null
。
示例
下面的示例演示如何在資源類中使用SuppressFinalize方法,以防止呼叫冗餘垃圾回收。該示例使用dispose 模式來釋放託管資源(即實現IDisposable的物件)和非託管資源。
C#using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
public class ConsoleMonitor : IDisposable
{
const int STD_INPUT_HANDLE = -10;
const int STD_OUTPUT_HANDLE = -11;
const int STD_ERROR_HANDLE = -12;
[DllImport("kernel32.dll",SetLastError = true)]
static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll",SetLastError = true)]
static extern bool WriteConsole(IntPtr hConsoleOutput,string lpBuffer,uint nNumberOfCharsToWrite,out uint lpNumberOfCharsWritten,IntPtr lpReserved);
[DllImport("kernel32.dll",SetLastError = true)]
static extern bool CloseHandle(IntPtr handle);
private bool disposed = false;
private IntPtr handle;
private Component component;
public ConsoleMonitor()
{
handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (handle == IntPtr.Zero)
throw new InvalidOperationException("A console handle is not available.");
component = new Component();
string output = "The ConsoleMonitor class constructor.\n";
uint written = 0;
WriteConsole(handle,(uint) output.Length,out written,IntPtr.Zero);
}
// The destructor calls Object.Finalize.
~ConsoleMonitor()
{
if (handle != IntPtr.Zero) {
string output = "The ConsoleMonitor finalizer.\n";
uint written = 0;
WriteConsole(handle,IntPtr.Zero);
}
else {
Console.Error.WriteLine("Object finalization.");
}
// Call Dispose with disposing = false.
Dispose(false);
}
public void Write()
{
string output = "The Write method.\n";
uint written = 0;
WriteConsole(handle,IntPtr.Zero);
}
public void Dispose()
{
string output = "The Dispose method.\n";
uint written = 0;
WriteConsole(handle,IntPtr.Zero);
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
string output = String.Format("The Dispose({0}) method.\n",disposing);
uint written = 0;
WriteConsole(handle,IntPtr.Zero);
// Execute if resources have not already been disposed.
if (! disposed) {
// If the call is from Dispose,free managed resources.
if (disposing) {
Console.Error.WriteLine("Disposing of managed resources.");
if (component != null)
component.Dispose();
}
// Free unmanaged resources.
output = "Disposing of unmanaged resources.";
WriteConsole(handle,IntPtr.Zero);
if (handle != IntPtr.Zero) {
if (! CloseHandle(handle))
Console.Error.WriteLine("Handle cannot be closed.");
}
}
disposed = true;
}
}
public class Example
{
public static void Main()
{
Console.WriteLine("ConsoleMonitor instance....");
ConsoleMonitor monitor = new ConsoleMonitor();
monitor.Write();
monitor.Dispose();
}
}
// If the monitor.Dispose method is not called,the example displays the following output:
// ConsoleMonitor instance....
// The ConsoleMonitor class constructor.
// The Write method.
// The ConsoleMonitor finalizer.
// The Dispose(False) method.
// Disposing of unmanaged resources.
//
// If the monitor.Dispose method is called,the example displays the following output:
// ConsoleMonitor instance....
// The ConsoleMonitor class constructor.
// The Write method.
// The Dispose method.
// The Dispose(True) method.
// Disposing of managed resources.
// Disposing of unmanaged resources.
註解
此方法設定obj
的物件標頭中的一個位,執行時在呼叫終結器時進行檢查。由Object.Finalize方法表示的終結器用於在對物件進行垃圾回收之前釋放非託管資源。如果obj
沒有終結器或 GC 已向終結器執行緒發出執行終結器的訊號,則對SuppressFinalize方法的呼叫不起作用。
實現IDisposable介面的物件可以從物件的IDisposable.Dispose實現中呼叫此方法,以防止垃圾回收器在不需要的物件上呼叫Object.Finalize。通常,這樣做是為了防止終結器釋放已由IDisposable.Dispose實現釋放的非託管資源。