আমি কখন GC.SuppressFinalize () ব্যবহার করব?


287

.NET- এ, কোন পরিস্থিতিতে আমার ব্যবহার করা উচিত GC.SuppressFinalize()?

এই পদ্ধতিটি ব্যবহার করে আমার কী লাভ (গুলি) করতে পারে?


আমি চূড়ান্তকরণকারী এবং আইডিস্পোজেবল সম্পর্কে কয়েকটি প্রশ্ন দেখেছি, স্ট্যাকওভারফ্লোতেও জিসি.সপ্রেসফাইনালাইজ এবং দুর্বল উল্লেখগুলি সম্পর্কে কিছু হওয়া উচিত
স্যাম

আমি মনে করি না দুর্বল রেফারেন্স চূড়ান্তকরণ সম্পর্কিত অনেক কিছুই করে - সম্ভবত তাদের সম্পর্কে আপনার আরও একটি সরাসরি প্রশ্ন পোস্ট করা উচিত।
মাইকেল বারার

ইয়ার্প আমি হ'ল দুর্বল রেফারগুলি সম্পর্কে একটি পৃথক প্রশ্ন পোস্ট করার অর্থ হ'ল, আপনি যখন অবজেক্ট পুল তৈরি করেন তখন এগুলি সবই এক সাথে বেঁধে দিতে পারে। এছাড়াও আমার অবজেক্ট রিভাইভাল আলা সম্পর্কে একটি প্রশ্ন জিজ্ঞাসা করা উচিত রেজিস্টার ফরফাইনালাইজ
স্যাম

উত্তর:


296

SuppressFinalizeচূড়ান্তরূপী শ্রেণীর দ্বারা কেবল কল করা উচিত। এটি আবর্জনা সংগ্রাহককে (জিসি) অবহিত করছে যে thisবিষয়টি পুরোপুরি পরিষ্কার হয়ে গেছে ed

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);
    }
}

সাধারণত, সিএলআর যখন তৈরি হয় তখন তাদের চূড়ান্তকরণের সাথে বস্তুগুলিতে ট্যাব রাখে (তাদের তৈরিতে আরও ব্যয়বহুল করে তোলে)। SuppressFinalizeজিসিকে বলুন যে অবজেক্টটি সঠিকভাবে পরিষ্কার করা হয়েছিল এবং চূড়ান্তকরণকারী সারিতে যাওয়ার দরকার নেই। এটি দেখতে C ++ ডিসস্ট্রাক্টরের মতো দেখায় তবে এর মতো কিছু করে না।

SuppressFinalizeঅপ্টিমাইজেশান হিসাবে আপনার বস্তু একটি দীর্ঘ সময়ের finalizer কিউ অপেক্ষায় থাকতে পারে, তুচ্ছ নয়। 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

1
প্রথম কোড স্নিপেটে আমি কেবলমাত্র প্রস্তাবিত আইডিস্পোজেবল + ফাইনালাইজার প্যাটার্ন দেখতে কেমন পোস্ট করছি। ডিবাগিং কোডটি ভাল তবে এটি বিভ্রান্তিকর হতে পারে। .. আমি কেবল পরিচালনা না করা সংস্থান আছে এমন ক্লাসগুলি বাদ দিয়ে চূড়ান্তকরণকারীদের এড়িয়ে চলার পরামর্শ দিতে পারি। নিরাপদ চূড়ান্তকরণ কোড লেখা অ-তুচ্ছ।
রবার্ট পলসন

1
হাই, চূড়ান্তকরণকারীর পরামিতি হিসাবে আমাদের মিথ্যা দিয়ে কেন নিষ্পত্তি করতে হবে? নিষ্পত্তি যদি কখনও কল না হয়ে থাকে এবং তবে তা নিষ্পত্তি হয় না? যদি আমরা কেবলমাত্র অবজেক্টটি নিষ্পত্তি করা হয়েছে কিনা এবং তা পরীক্ষা করে নিই এবং আসল ক্লিনআপ করি কিনা।
ড্রিমার

3
@ ড্রিমার - এটি আপনার প্রয়োগের উপর নির্ভর করে। সাধারণভাবে আপনি জানতে চান যে আইডিস্পোজেবল বনাম চূড়ান্তকরণকারক দ্বারা ডিসপোজ ডেকে আনা হচ্ছে D ডিসপোজ () বাস্তবায়ন। যদি চূড়ান্তকরণকারীর কাছ থেকে আহ্বান করা হয়, আপনাকে অবশ্যই ধরে নিতে হবে যে ব্যক্তিগত রেফারেন্সগুলি আর বৈধ নয় এবং আপনি সত্যিই খুব বেশি কিছু করতে পারবেন না। যদিও আইডিস্পোজেবল থেকে ডেকে আনা হয়েছে is ডিসপোজ (), আপনি জানেন যে রেফারেন্সগুলি এখনও বৈধ।
রবার্ট পলসন

32
যদি শ্রেণি প্রয়োগকারী IDisposableনা হয় sealed, তবে এটিতে GC.SuppressFinalize(this) কোনও ব্যবহারকারী-সংজ্ঞায়িত চূড়ান্তকরণকারীর অন্তর্ভুক্ত না হলেও কলটিতে এটি অন্তর্ভুক্ত করা উচিত । এটি উদ্ভুত প্রকারের জন্য উপযুক্ত শব্দার্থবিজ্ঞান নিশ্চিত করতে প্রয়োজনীয় যা কোনও ব্যবহারকারী-সংজ্ঞায়িত ফাইনালাইজার যুক্ত করে তবে কেবল সুরক্ষিত Dispose(bool)পদ্ধতিকে ওভাররাইড করে ।
স্যাম হারওয়েল

1
sealedউদ্ভূত শ্রেণীর জন্য @ সামহরওয়েল দ্বারা উল্লিখিত না হওয়া গুরুত্বপূর্ণ is কোডএনালাইসিসের ফলাফল যখন ca1816 + ca1063 হয় যখন শ্রেণিটি সিল না করা হয় তবে সিল করা ক্লাসগুলি ব্যতীত ভাল থাকে SuppressFinalize
ড্যাশসি

38

SupressFinalizeসিস্টেমকে বলে যে চূড়ান্তকরণে যা কিছু করা হত তা ইতিমধ্যে সম্পন্ন হয়েছে, সুতরাং চূড়ান্তকরণকারীর ডাক দেওয়ার দরকার নেই। .NET ডক্স থেকে:

আইডিস্পোজেবল ইন্টারফেস বাস্তবায়নকারী অবজেক্টগুলি আইডিস্পোজেবল থেকে এই পদ্ধতিটি কল করতে পারে the আবর্জনা সংগ্রহকারীকে অবজেক্ট কল করা থেকে বিরত রাখতে ডিসপোজ পদ্ধতি method

সাধারণভাবে, যে কোনও Dispose()পদ্ধতিতে কল করতে সক্ষম হওয়া উচিত GC.SupressFinalize(), কারণ এটি চূড়ান্তকরণে পরিষ্কার করা সমস্ত কিছু পরিষ্কার করা উচিত।

SupressFinalizeকেবলমাত্র এমন একটি বিষয় যা একটি অপ্টিমাইজেশন সরবরাহ করে যা সিস্টেমটিকে চূড়ান্তকরণের থ্রেডে অবজেক্টের কাতারে বিরক্ত করতে দেয় না। একটি সঠিকভাবে লিখিত Dispose()/ চূড়ান্তকরণকারীকে কল করার সাথে বা ছাড়াই সঠিকভাবে কাজ করা উচিত GC.SupressFinalize()


2

সেই পদ্ধতিটি কার্যকর করতে সক্ষম Disposeঅবজেক্টগুলির পদ্ধতিতে অবশ্যই IDisposableকল করতে হবে, এই পদ্ধতিতে কোনও ব্যক্তি যদি Disposeপদ্ধতিটি কল করে তবে জিসি চূড়ান্ততরিকে আর একবার কল করবে না ।

দেখুন: GC.SuppressFinalize (অবজেক্ট) পদ্ধতি - মাইক্রোসফ্ট ডক্স


9
আমার মনে হয় "আবশ্যক" ভুল - এমনকি "হওয়া উচিত নয়" - এটি এমনই যে কিছু পরিস্থিতিতে আপনি অবজেক্টটিকে সারিবদ্ধ / চূড়ান্ত করার ওভারহেডটি সরিয়ে ফেলতে পারেন।
বেসিক

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

যদি অবজেক্টের ফাইনালাইজার থাকে তবে। নেট চূড়ান্তকরণের সারিতে একটি রেফারেন্স রাখে।

যেহেতু আমাদের কল রয়েছে Dispose(ture), এটি স্পষ্ট অবজেক্ট, সুতরাং এই কাজটি করার জন্য আমাদের চূড়ান্তকরণের সারির দরকার নেই।

তাই GC.SuppressFinalize(this)চূড়ান্তকরণের সারিতে কল অপসারণ রেফারেন্স।


0

যদি কোনও শ্রেণি, বা এটি থেকে প্রাপ্ত কোনও কিছু ফাইনালেরাইজারের সাথে কোনও বস্তুর সর্বশেষ লাইভ রেফারেন্স ধরে রাখতে পারে, তবে সেই চূড়ান্তকরণকারীর দ্বারা বিরূপ প্রভাবিত হতে পারে এমন কোনও ক্রিয়াকলাপের পরেও তাকে GC.SuppressFinalize(this)বা GC.KeepAlive(this)বস্তুটির কাছে ডাকা উচিত, এভাবে ফাইনালাইজার জিতেছে তা নিশ্চিত করে অপারেশন সম্পূর্ণ না হওয়া পর্যন্ত চলবে না।

চূড়ান্তকরণকারী নেই এমন কোনও ক্লাসে ব্যয় GC.KeepAlive()এবং GC.SuppressFinalize(this)মূলত একইরকম এবং চূড়ান্তকরণকারীদের ক্লাসগুলির সাধারণত কল করা উচিত GC.SuppressFinalize(this), সুতরাং শেষের কাজ হিসাবে শেষের কাজটি Dispose()সর্বদা প্রয়োজনীয় নাও হতে পারে তবে এটি হবে না তুমি ভুল.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.