سؤال

في .NET، تحت أي ظروف يجب أن أستخدمه GC.SuppressFinalize()?

ما هي الميزة (المزايا) التي يمنحني إياها استخدام هذه الطريقة؟

هل كانت مفيدة؟

المحلول

يجب أن يتم استدعاء SuppressFinalize فقط بواسطة فئة تحتوي على أداة نهائية.إنها تبلغ جامع البيانات المهملة (GC) بذلك this تم تنظيف الكائن بالكامل.

نمط IDisposable الموصى به عندما يكون لديك أداة نهائية هو:

public class MyClass : IDisposable
{
    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                // called via myClass.Dispose(). 
                // OK to use any private object references
            }
            // Release unmanaged resources.
            // Set large fields to null.                
            disposed = true;
        }
    }

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

    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
}

عادةً، يحتفظ CLR بعلامات تبويب على الكائنات ذات أداة الإنهاء عند إنشائها (مما يجعل إنشاءها أكثر تكلفة).يخبر SuppressFinalize GC أنه تم تنظيف الكائن بشكل صحيح ولا يحتاج إلى الانتقال إلى قائمة انتظار الإنهاء.يبدو وكأنه مدمر C++، لكنه لا يعمل مثله.

لا يعد تحسين SuppressFinalize أمرًا تافهًا، حيث يمكن أن تعيش كائناتك لفترة طويلة في انتظار قائمة انتظار الإنهاء.لا تميل إلى استدعاء SuppressFinalize على كائنات أخرى تخطر ببالك.وهذا عيب خطير في انتظار أن يحدث.

تخبرنا إرشادات التصميم أن أداة الإنهاء ليست ضرورية إذا كان الكائن الخاص بك يطبق IDisposable، ولكن إذا كان لديك أداة الإنهاء، فيجب عليك تنفيذ IDisposable للسماح بالتنظيف الحتمي لفصلك.

في معظم الأوقات، يجب أن تكون قادرًا على التخلص من IDisposable لتنظيف الموارد.يجب أن تحتاج إلى أداة الإنهاء فقط عندما يحتفظ كائنك بموارد غير مُدارة وتحتاج إلى ضمان تنظيف هذه الموارد.

ملحوظة:في بعض الأحيان، يضيف المبرمجون أداة نهائية لتصحيح أخطاء إصدارات فئات IDisposable الخاصة بهم من أجل اختبار أن التعليمات البرمجية قد تخلصت من كائن IDisposable الخاص بهم بشكل صحيح.

    public void Dispose() // Implement IDisposable
    {
        Dispose(true);
    #if DEBUG
        GC.SuppressFinalize(this);
    #endif
    }

    #if DEBUG
    ~MyClass() // the finalizer
    {
        Dispose(false);
    }
    #endif

نصائح أخرى

أنت تخبر النظام أن أي عمل كان سيتم إنجازه في أداة الإنهاء قد تم إنجازه بالفعل، لذا لا يلزم استدعاء أداة الإنهاء.من مستندات .NET:

يمكن للكائنات التي تنفذ واجهة idisposable استدعاء هذه الطريقة من طريقة Idisposable.dispose لمنع جامع القمامة من استدعاء الكائن.

بشكل عام، معظم أساليب Dispose() يجب أن تكون قادرة على استدعاء GC.SupressFinalize()، لأنها يجب أن تنظف كل ما سيتم تنظيفه في أداة الإنهاء.

SupressFinalize هو مجرد شيء يوفر تحسينًا يسمح للنظام بعدم إزعاج الكائن في قائمة الانتظار في مؤشر ترابط الإنهاء.يجب أن يعمل Dispose()/finalizer المكتوب بشكل صحيح بشكل صحيح مع أو بدون استدعاء GC.SupressFinalize().

يجب استدعاء هذه الطريقة في طريقة التخلص من الكائنات التي تقوم بتنفيذ IDisposable، وبهذه الطريقة لن يقوم GC باستدعاء أداة الإنهاء مرة أخرى إذا قام شخص ما باستدعاء طريقة التخلص.

يرى: http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize.aspx

 Dispose(true);
 GC.SuppressFinalize(this);

إذا كان الكائن يحتوي على أداة نهائية، فإن .net يضع مرجعًا في قائمة انتظار الإنهاء

نظرًا لأننا قمنا باستدعاء Dispose(ture)، فهو كائن واضح، لذلك لا نحتاج إلى قائمة انتظار الإنهاء للقيام بهذه المهمة.

لذا اتصل بـ GC.SuppressFinalize(this) لإزالة المرجع في قائمة انتظار الإنهاء.

إذا كان من الممكن أن تحتوي فئة ما، أو أي شيء مشتق منها، على آخر مرجع مباشر لكائن ذي أداة نهائية، فعندئذ إما GC.SuppressFinalize(this) أو GC.KeepAlive(this) يجب استدعاؤه على الكائن بعد أي عملية قد تتأثر سلبًا بأداة الإنهاء هذه، وبالتالي ضمان عدم تشغيل أداة الإنهاء إلا بعد اكتمال هذه العملية.

السعر ل GC.KeepAlive() و GC.SuppressFinalize(this) هي نفسها بشكل أساسي في أي فصل لا يحتوي على أداة إنهاء، ويجب بشكل عام استدعاء الفئات التي تحتوي على أداة إنهاء GC.SuppressFinalize(this), ، لذا استخدم الوظيفة الأخيرة كخطوة أخيرة Dispose() قد لا يكون ذلك ضروريًا دائمًا، لكنه لن يكون خطأً.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top