সি # তে চূড়ান্ত / নিষ্পত্তি পদ্ধতির ব্যবহার


381

সি # ২০০৮

আমি এখনই কিছুক্ষণ ধরে এটি নিয়ে কাজ করছি এবং কোডের ক্ষেত্রে চূড়ান্তকরণ এবং নিষ্পত্তি করার পদ্ধতিগুলি সম্পর্কে আমি এখনও বিভ্রান্ত। আমার প্রশ্নগুলি নীচে রয়েছে:

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

  2. তবে, আমি যদি এমন কোনও শ্রেণীর বিকাশ করি যা প্রত্যক্ষ বা অপ্রত্যক্ষভাবে কোনও পরিচালনা না করা সংস্থান ব্যবহার করে না, আমি কি IDisposableএই শ্রেণীর ক্লায়েন্টদের 'ব্যবহারের বিবৃতি' ব্যবহারের অনুমতি দেওয়ার জন্য বাস্তবায়ন করব ?

    কেবলমাত্র আপনার ক্লাসের ক্লায়েন্টদের ব্যবহারের বিবৃতিটি ব্যবহার করতে সক্ষম করতে আইডিপোজেবলকে বাস্তবায়ন করা কি সম্ভব হবে?

    using(myClass objClass = new myClass())
    {
        // Do stuff here
    }
  3. চূড়ান্তকরণ / নিষ্পত্তি করার ব্যবহারটি প্রদর্শনের জন্য আমি নীচে এই সাধারণ কোডটি বিকাশ করেছি:

    public class NoGateway : IDisposable
    {
        private WebClient wc = null;
    
        public NoGateway()
        {
            wc = new WebClient();
            wc.DownloadStringCompleted += wc_DownloadStringCompleted;
        }
    
    
        // Start the Async call to find if NoGateway is true or false
        public void NoGatewayStatus()
        {
            // Start the Async's download
                // Do other work here
            wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
        }
    
        private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            // Do work here
        }
    
        // Dispose of the NoGateway object
        public void Dispose()
        {
            wc.DownloadStringCompleted -= wc_DownloadStringCompleted;
            wc.Dispose();
            GC.SuppressFinalize(this);
        }
    }

উত্স কোড সম্পর্কে প্রশ্ন:

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

    সুতরাং উদাহরণস্বরূপ আমার ক্লাসটিকে নোগেটওয়ে বলা হয় এবং ক্লায়েন্টটি ক্লাসটি এভাবে ব্যবহার করতে এবং নিষ্পত্তি করতে পারে:

    using(NoGateway objNoGateway = new NoGateway())
    {
        // Do stuff here   
    }

    এক্সিকিউশনটি ব্যবহারের ব্লকের শেষে পৌঁছে গেলে কি ডিসপোজ পদ্ধতিটি স্বয়ংক্রিয়ভাবে কল হবে বা ক্লায়েন্টকে ম্যানুয়ালি ডিসপোজ পদ্ধতিতে কল করতে হবে? অর্থাত

    NoGateway objNoGateway = new NoGateway();
    // Do stuff with object
    objNoGateway.Dispose(); // finished with it
  2. আমি WebClientআমার NoGatewayক্লাসে ক্লাসটি ব্যবহার করছি । কারণ ইন্টারফেস WebClientপ্রয়োগ করে IDisposable, এর অর্থ কি WebClientপরোক্ষভাবে অপরিকল্পিত সংস্থান ব্যবহার করে? এটি অনুসরণ করার জন্য কি কোনও কঠোর এবং দ্রুত নিয়ম রয়েছে? আমি কীভাবে জানতে পারি যে কোনও শ্রেণি অবরুদ্ধ পরিচালিত সংস্থান ব্যবহার করে?


1
এই জটিল নকশার প্যাটার্নটি কি আসলে এই সংস্থান সম্পর্কিত সমস্যা সমাধানের জন্য প্রয়োজন?
zinking

উত্তর:


422

প্রস্তাবিত আইডিস্পোজেবল প্যাটার্নটি এখানে । আইডিস্পোজেবল ব্যবহার করে এমন কোনও ক্লাস প্রোগ্রামিং করার সময় সাধারণত আপনার দুটি প্যাটার্ন ব্যবহার করা উচিত:

কোনও সিলড ক্লাস প্রয়োগ করার সময় যা নিয়ন্ত্রণহীন সংস্থানগুলি ব্যবহার করে না, আপনি কেবল সাধারণ ইন্টারফেস প্রয়োগের মতো একটি ডিসপোজ পদ্ধতি প্রয়োগ করেন:

public sealed class A : IDisposable
{
    public void Dispose()
    {
        // get rid of managed resources, call Dispose on member variables...
    }
}

একটি অনিবন্ধিত শ্রেণি প্রয়োগ করার সময়, এটি এর মতো করুন:

public class B : IDisposable
{    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // get rid of managed resources
        }   
        // get rid of unmanaged resources
    }

    // only if you use unmanaged resources directly in B
    //~B()
    //{
    //    Dispose(false);
    //}
}

লক্ষ্য করুন যে আমি কোনও চূড়ান্ত ঘোষণা করি নি B; আপনার কাছে কেবলমাত্র চূড়ান্তকরণ কার্যকর করতে হবে যদি আপনার নিষ্পত্তি করার জন্য সত্যিকারের পরিচালনা ব্যবস্থা নেই। সিএলআর চূড়ান্তকরণযোগ্য অবজেক্টের সাথে চূড়ান্তভাবে অ-চূড়ান্তযোগ্য বস্তুগুলির সাথে ডিল করে, এমনকি যদি SuppressFinalizeবলা হয়।

সুতরাং, আপনার দরকার না হলে আপনার চূড়ান্ত ঘোষণা করা উচিত নয়, তবে আপনি আপনার শ্রেণির উত্তরাধিকারীদের আপনার কল করতে Disposeএবং একটি চূড়ান্তকরণকারীর নিজেরাই প্রয়োগ করতে হুক দেন, যদি তারা সরাসরি পরিচালনা না করা সংস্থান ব্যবহার করেন:

public class C : B
{
    private IntPtr m_Handle;

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // get rid of managed resources
        }
        ReleaseHandle(m_Handle);

        base.Dispose(disposing);
    }

    ~C() {
        Dispose(false);
    }
}

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

যখন কোনও শ্রেণি আইডিস্পোজেবল ইন্টারফেস প্রয়োগ করে, এর অর্থ হ'ল কোথাও কোথাও এমন কিছু ব্যবস্থাবিহীন সংস্থান রয়েছে যা আপনি ক্লাসটি ব্যবহার শেষ করার পরে পরিত্রাণ পাবেন। আসল সংস্থানগুলি ক্লাসের মধ্যেই আবদ্ধ হয়; আপনার এগুলি স্পষ্টভাবে মুছতে হবে না। ক্লাসটিকে কেবল কল করা Dispose()বা মোড়ানো এটি using(...) {}নিশ্চিত করে দেবে যে কোনও অপ্রয়োজনীয় সম্পদ প্রয়োজনীয় হিসাবে মুক্তি পেয়েছে of


26
আমি কুকুপের সাথে একমত মনে রাখবেন যে আপনি যদি কেবল পরিচালিত সংস্থানসমূহ নিয়েই কাজ করেন তবে আপনাকে ফাইনালাইজারের প্রয়োজন হবে না (প্রকৃতপক্ষে, আপনার চূড়ান্তকরণকারীর মধ্যে থেকে "" এটি "ব্যতীত) পরিচালিত বস্তুগুলি অ্যাক্সেস করার চেষ্টা করা উচিত নয়, কারণ এতে কোনও গ্যারান্টিযুক্ত অর্ডার নেই জিসি অবজেক্টগুলি পরিষ্কার করে দেবে। এছাড়াও, আপনি যদি নেট .০.০ বা আরও বেশি বেশি ব্যবহার করেন তবে আপনি নিরাপদহ্যান্ডলগুলি অনিয়ন্ত্রিত হ্যান্ডলগুলি মোড়ানোর জন্য ব্যবহার করতে পারেন (এবং হওয়া উচিত) Safe সেফহ্যান্ডলগুলি আপনার পরিচালিত শ্রেণীর জন্য ফাইনালাইজারগুলি লেখার প্রয়োজনটি একেবারে হ্রাস করে। ব্লগস.এমএসএনএন। com / bclteam / সংরক্ষণাগার / 2005/03/16 / 396900.aspx
জেমার্চ

5
আমি মনে করি মেসেজবক্সে কল করা ভাল। ফিনালাইজারে দেখান ("ত্রুটি," + গেটটাইপ () Name নাম + "নিষ্পত্তি নয়"), কারণ ডিসপোজেবল অবজেক্টটি সর্বদা নিষ্পত্তি করা উচিত, এবং আপনি যদি এটি করতে ব্যর্থ হন তবে যত তাড়াতাড়ি সম্ভব সত্য সচেতন করা সেরা।
এরিক্ক্যালেন

95
@ এরিক্কল্লেন কি এটি একটি রসিকতা? :)
অ্যালেক্স নরক্লিফ

2
সক্রিয় চূড়ান্তকরণকারীর সাথে ক্লাসের ট্র্যাক রাখতে সিএলআর-তে অতিরিক্ত কম্পিউটিং প্রচেষ্টা প্রয়োজন। - একটি চূড়ান্তকরণকারী কার্যকর করা এর ফলে ঘটে। জিসি.সপ্রেসফাইনালাইজ কল করার অর্থ ফাইনালাইজারটি রানটাইম দ্বারা কল করা উচিত নয়। এটি এখনও জেন 2 যায় নির্বিশেষে। আপনি যদি পরিচালিত সংস্থাগুলি নিয়ে কাজ না করে থাকেন তবে ফাইনালাইজার যুক্ত করবেন না। সিলযুক্ত বা সিল না করা শ্রেণি সংশোধনকারীরা সেই বিন্দুর সাথে অপ্রাসঙ্গিক।
রিচ মেল্টন

3
@ রিচ: উদ্ধৃতি? এটি অগত্যা কোনও খারাপ জিনিস নয়; যদি আপনি বাস্তবায়ন করেন তবে IDisposableসম্ভাবনা হ'ল এটি যেহেতু কিছু সময়ের জন্য স্থির থাকবে। আপনি সিএনআর-কে জেন0
থিওপ

123

বাস্তবায়নের সরকারী প্যাটার্নটি IDisposableবোঝা শক্ত। আমি বিশ্বাস করি এটি আরও ভাল :

public class BetterDisposableClass : IDisposable {

  public void Dispose() {
    CleanUpManagedResources();
    CleanUpNativeResources();
    GC.SuppressFinalize(this);
  }

  protected virtual void CleanUpManagedResources() { 
    // ...
  }
  protected virtual void CleanUpNativeResources() {
    // ...
  }

  ~BetterDisposableClass() {
    CleanUpNativeResources();
  }

}

একটি আরও ভাল সমাধান হ'ল একটি নিয়ম থাকা উচিত যে আপনি যে কোনও পরিচালনা না করা সম্পদ হ্যান্ডেল করার জন্য আপনাকে সর্বদা একটি মোড়কের ক্লাস তৈরি করতে হবে:

public class NativeDisposable : IDisposable {

  public void Dispose() {
    CleanUpNativeResource();
    GC.SuppressFinalize(this);
  }

  protected virtual void CleanUpNativeResource() {
    // ...
  }

  ~NativeDisposable() {
    CleanUpNativeResource();
  }

}

সঙ্গে SafeHandleএবং তার ডেরাইভেটিভস, এই শ্রেণীর হওয়া উচিত খুব বিরল

ডিসপোজেবল শ্রেণীর জন্য ফলাফল যা নিয়ন্ত্রিত সংস্থাগুলির সাথে সরাসরি চুক্তি করে না, এমনকি উত্তরাধিকারের উপস্থিতিতেও, শক্তিশালী: তাদের আর নিয়ন্ত্রণহীন সম্পদের সাথে উদ্বিগ্ন হওয়ার দরকার নেই । এগুলি বাস্তবায়ন এবং বুঝতে সহজ হবে:

public class ManagedDisposable : IDisposable {

  public virtual void Dispose() {
    // dispose of managed resources
  }

}

@ কাইল: ধন্যবাদ! আমি এটি অনুসরণ করা এটা খুব :-) আছে মত এখানে
জর্দো

4
যদিও আমি একটি জিনিস লক্ষ করতে চাই তা হ'ল এটি দ্বিতীয়বার বলা থেকে বাধা দেয় না।
হুসিইনস্লু

5
@ হুসেইন উসলু: এটি কেবল প্যাটার্নের সারমর্ম । আপনি অবশ্যই একটি disposedপতাকা যুক্ত করতে পারেন এবং সেই অনুযায়ী চেক করতে পারেন ।
জর্দো

2
@ ডিডিবাস: এটি একটি disposedপতাকা যুক্ত করার সাধারণ বিষয়, নিষ্পত্তি করার আগে এটি পরীক্ষা করে তা নিষ্পত্তি করার পরে সেট করুন। ধারণা জন্য এখানে দেখুন । ক্লাসের কোনও পদ্ধতির আগে আপনার পতাকাও পরীক্ষা করা উচিত। বোধ হয়? এটা কি জটিল?
জর্দো

1
জন্য +1 "একটি আরো উন্নত সমাধান একটি নিয়ম আপনি সবসময় কোন অপরিচালিত রিসোর্সে একটি রাপার ক্লাস তৈরি করতে আপনি হাতল প্রয়োজন আছে আছে হল" । আমি ভিএলসির জন্য একটি অ্যাডনে এটি পেরেছি এবং আমি তখন থেকেই এটি ব্যবহার করে আসছি it অনেক মাথাব্যথা বাঁচায় ...
ফ্রেঞ্চ বি।

37

নোট করুন যে কোনও IDisposable বাস্তবায়ন নীচের প্যাটার্ন অনুসরণ করা উচিত (IMHO)। আমি বেশ কয়েকটি দুর্দান্ত .NET "দেবতা" দের কাছ থেকে প্রাপ্ত তথ্যের ভিত্তিতে এই প্যাটার্নটি বিকাশ করেছি .NET ফ্রেমওয়ার্ক ডিজাইন নির্দেশিকাগুলির (নোট করুন যে এমএসডিএন কোনও কারণে এটি অনুসরণ করে না!)! .NET ফ্রেমওয়ার্ক ডিজাইনের গাইডলাইনগুলি ক্রজিৎস্টোফ ক্লওয়িনা (সে সময় সিএলআর আর্কিটেক্ট) এবং ব্র্যাড আব্রামস (আমি বিশ্বাস করি সে সময় সিএলআর প্রোগ্রাম ম্যানেজার) এবং বিল ওয়াগনার ([কার্যকর সি #] এবং [আরও কার্যকর সি #] লিখেছিলেন) এ্যামাজন ডটকম এ দেখুন:

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

আমি যে প্যাটার্নটি একসাথে রেখেছি (এবং এর জন্য কোড স্নিপেট লিখেছি) নীচে:

#region IDisposable implementation

//TODO remember to make this class inherit from IDisposable -> $className$ : IDisposable

// Default initialization for a bool is 'false'
private bool IsDisposed { get; set; }

/// <summary>
/// Implementation of Dispose according to .NET Framework Design Guidelines.
/// </summary>
/// <remarks>Do not make this method virtual.
/// A derived class should not be able to override this method.
/// </remarks>
public void Dispose()
{
    Dispose( true );

    // This object will be cleaned up by the Dispose method.
    // Therefore, you should call GC.SupressFinalize to
    // take this object off the finalization queue 
    // and prevent finalization code for this object
    // from executing a second time.

    // Always use SuppressFinalize() in case a subclass
    // of this type implements a finalizer.
    GC.SuppressFinalize( this );
}

/// <summary>
/// Overloaded Implementation of Dispose.
/// </summary>
/// <param name="isDisposing"></param>
/// <remarks>
/// <para><list type="bulleted">Dispose(bool isDisposing) executes in two distinct scenarios.
/// <item>If <paramref name="isDisposing"/> equals true, the method has been called directly
/// or indirectly by a user's code. Managed and unmanaged resources
/// can be disposed.</item>
/// <item>If <paramref name="isDisposing"/> equals false, the method has been called by the 
/// runtime from inside the finalizer and you should not reference 
/// other objects. Only unmanaged resources can be disposed.</item></list></para>
/// </remarks>
protected virtual void Dispose( bool isDisposing )
{
    // TODO If you need thread safety, use a lock around these 
    // operations, as well as in your methods that use the resource.
    try
    {
        if( !this.IsDisposed )
        {
            if( isDisposing )
            {
                // TODO Release all managed resources here

                $end$
            }

            // TODO Release all unmanaged resources here



            // TODO explicitly set root references to null to expressly tell the GarbageCollector
            // that the resources have been disposed of and its ok to release the memory allocated for them.


        }
    }
    finally
    {
        // explicitly call the base class Dispose implementation
        base.Dispose( isDisposing );

        this.IsDisposed = true;
    }
}

//TODO Uncomment this code if this class will contain members which are UNmanaged
// 
///// <summary>Finalizer for $className$</summary>
///// <remarks>This finalizer will run only if the Dispose method does not get called.
///// It gives your base class the opportunity to finalize.
///// DO NOT provide finalizers in types derived from this class.
///// All code executed within a Finalizer MUST be thread-safe!</remarks>
//  ~$className$()
//  {
//     Dispose( false );
//  }
#endregion IDisposable implementation

একটি উদ্ভূত শ্রেণিতে IDisposable বাস্তবায়নের জন্য কোড এখানে। নোট করুন যে উত্পন্ন শ্রেণীর সংজ্ঞাতে আপনার স্পষ্টরূপে আইডিজিপোজযোগ্য থেকে উত্তরাধিকার তালিকাভুক্ত করার দরকার নেই।

public DerivedClass : BaseClass, IDisposable (remove the IDisposable because it is inherited from BaseClass)


protected override void Dispose( bool isDisposing )
{
    try
    {
        if ( !this.IsDisposed )
        {
            if ( isDisposing )
            {
                // Release all managed resources here

            }
        }
    }
    finally
    {
        // explicitly call the base class Dispose implementation
        base.Dispose( isDisposing );
    }
}

আমি আমার ব্লগে এই প্রয়োগটি পোস্ট করেছি: কীভাবে ডিসপোজ প্যাটার্নটি যথাযথভাবে প্রয়োগ করতে হবে


কেউ কি কোনও উত্পন্ন শ্রেণীর (এই বেস শ্রেণীর থেকে প্রাপ্ত) জন্য একটি প্যাটার্ন যুক্ত করতে পারেন
akjoshi

3
@akjoshi - উদ্ভূত নিষ্পত্তিযোগ্য ক্লাসের কোড অন্তর্ভুক্ত করার জন্য আমি উপরের প্যাটার্নটি আপডেট করেছি। আরও মনে রাখবেন, ডেরিভড ক্লাসে কোনও ফাইনালাইজার প্রয়োগ করবেন না ...
ডেভ ব্ল্যাক

3
মাইক্রোসফ্ট মনে হয় নিষ্পত্তি পদ্ধতির শেষে "নিষ্পত্তি" পতাকা সেট করা পছন্দ করে তবে এটি আমার কাছে ভুল বলে মনে হয়। "নিষ্পত্তি" এ অপ্রয়োজনীয় কলগুলি কিছুই করার কথা নয়; যদিও কেউ সাধারণত ডিসপোজকে পুনরাবৃত্তভাবে ডাকা হবে বলে আশা করে না, যদি কেউ নির্মাণ বা অন্য কোনও ক্রিয়াকলাপ চলাকালীন ঘটে যাওয়া একটি ব্যতিক্রম দ্বারা একটি অবৈধ অবস্থায় রেখে যাওয়া কোনও বস্তুকে ডিসপোজ করার চেষ্টা করে থাকে তবে এই জিনিসগুলি ঘটতে পারে। আমি ভাবব অ-ভার্চুয়াল মোড়ক ফাংশনে Interlocked.Exchangeএকটি পূর্ণসংখ্যার IsDisposedপতাকা ব্যবহার করা আরও নিরাপদ।
সুপারক্যাট

@ ডেভ ব্ল্যাক: আপনার বেস ক্লাসটি যদি নিয়ন্ত্রণহীন সংস্থান ব্যবহার না করে তবে আপনার উত্পন্ন শ্রেণিটি কী করবে? তাহলে কি আপনাকে ডেরিভড ক্লাসে ফাইনালাইজার প্রয়োগ করতে হবে? এবং যদি তা হয় তবে আপনি কীভাবে জানবেন যে উত্স অ্যাক্সেস না থাকলে বেস ক্লাস ইতিমধ্যে এটি প্রয়োগ করে নি?
দিদিয়ার এ।

@ ডেভ ব্ল্যাক "আমি বেশ কয়েকটি দুর্দান্ত। নেট" godsশ্বর "" থেকে প্রাপ্ত তথ্যের ভিত্তিতে এই প্যাটার্নটি তৈরি করেছি "যদি দেবতাদের মধ্যে একজন যদি জোন স্কিট ছিলেন তবে আমি আপনার পরামর্শ অনুসরণ করব।
এলিজাবেথ

23

আমি pm100 এর সাথে একমত (এবং আমার আগের পোস্টে স্পষ্টভাবে এটি বলা উচিত ছিল)।

আপনার প্রয়োজন না হলে আপনার কখনই কোনও ক্লাসে আইডিস্পোজেবল কার্যকর করা উচিত নয়। খুব সুনির্দিষ্ট হওয়ার জন্য, প্রায় 5 বার যখন আপনার প্রয়োজন হয় / আইডিস্পোজেবল বাস্তবায়ন করা উচিত:

  1. আপনার শ্রেণিতে সুস্পষ্টভাবে (যেমন উত্তরাধিকারের মাধ্যমে নয়) রয়েছে এমন কোনও পরিচালিত সংস্থান রয়েছে যা আইডিজিপোজেবল বাস্তবায়ন করে এবং আপনার ক্লাসটি আর ব্যবহার না করে একবার পরিষ্কার করা উচিত। উদাহরণস্বরূপ, যদি আপনার শ্রেণিতে স্ট্রিম, ডিবিকম্যান্ড, ডেটা টেবিল ইত্যাদির উদাহরণ থাকে if

  2. আপনার ক্লাসে স্পষ্টভাবে এমন কোনও পরিচালিত সংস্থান রয়েছে যা কোনও ক্লোজ () পদ্ধতি প্রয়োগ করে - যেমন আইডাটাআরডার, আইডিবি সংযোগ ইত্যাদি Note নোট করুন যে এই শ্রেণীর কিছুগুলি ডিসপোজ () পাশাপাশি একটি ক্লোজ () পদ্ধতি থাকার মাধ্যমে আইডিপোজেবল বাস্তবায়ন করে।

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

  4. যদি আপনার শ্রেণি দৃ strong় উল্লেখগুলি ব্যবহার করে ইভেন্টগুলিতে সাবস্ক্রাইব করে। ইভেন্টগুলি থেকে নিজেকে নিবন্ধভুক্ত / বিচ্ছিন্ন করতে হবে। সর্বদা তা নিশ্চিত করার জন্য নিবন্ধভুক্ত / বিচ্ছিন্ন করার চেষ্টা করার আগে এগুলি প্রথমে শূন্য নয়!

  5. আপনার ক্লাসে উপরের যে কোনও সমন্বয় রয়েছে ...

সিওএম অবজেক্টের সাথে কাজ করার এবং মার্শাল ব্যবহার করার জন্য একটি প্রস্তাবিত বিকল্প e রিলেজকম-অবজেক্ট () হ'ল সিস্টেম.রুনটাইম.আইএনটারপ সার্ভিসস.সেফহ্যান্ডেল ক্লাস ব্যবহার করা।

ছাত্রলীগের (বেস ক্লাস লাইব্রেরি টিম) এটি সম্পর্কে একটি ভাল ব্লগ পোস্ট রয়েছে এখানে http://blogs.msdn.com/bclteam/archive/2005/03/16/396900.aspx

একটি অত্যন্ত গুরুত্বপূর্ণ নোটটি তৈরি করা হ'ল আপনি যদি ডাব্লুসিএফের সাথে কাজ করছেন এবং সংস্থানগুলি পরিষ্কার করছেন তবে আপনার সর্বদা 'ব্যবহার' ব্লক এড়ানো উচিত। কেন এটি খারাপ ধারণা তা নিয়ে প্রচুর ব্লগ পোস্ট রয়েছে এবং এমএসডিএন-তে রয়েছে on আমি এটি সম্পর্কে এখানে পোস্টও করেছি - ডাব্লুসিএফ প্রক্সি সহ 'ব্যবহার করে () ব্যবহার করবেন না


3
আমি বিশ্বাস করি যে এখানে একটি 5 তম কেস রয়েছে: যদি আপনার শ্রেণি শক্তিশালী রেফারেন্স ব্যবহার করে ইভেন্টগুলিতে সাবস্ক্রাইব করে তবে আপনার আইডিস্পোজযোগ্য প্রয়োগ করা উচিত এবং ডিসপোজ পদ্ধতিতে ইভেন্টগুলি থেকে নিজেকে নিবন্ধিত করুন।
দিদিয়ার এ।

হাই দিদিবাস। হ্যাঁ আপনি সঠিক. আমি যে এক সম্পর্কে ভুলে গেছি। আমি আমার উত্তর পরিবর্তন করেছি যে এটি কেস হিসাবে অন্তর্ভুক্ত করতে। ধন্যবাদ।
ডেভ ব্ল্যাক

নিষ্পত্তি প্যাটার্নের জন্য এমএসডিএন ডকুমেন্টেশন আরও একটি কেস যুক্ত করেছে: "ক্লাসে বেসিক ডিসপোজ প্যাটার্ন প্রয়োগকারী কনসাইডার যেহেতু তারা নিজেরাই ব্যবস্থাপনিত সংস্থান বা নিষ্পত্তিযোগ্য বস্তু রাখে না তবে তাদের সাব টাইপগুলি রয়েছে এমন সম্ভাবনা রয়েছে this এর একটি দুর্দান্ত উদাহরণ সিস্টেম.আইও স্ট্রিম ক্লাস। যদিও এটি একটি বিমূর্ত বেস ক্লাস যা কোনও সংস্থান রাখে না, তার বেশিরভাগ সাবক্লাসগুলি এবং এর কারণে এটি এই প্যাটার্নটি প্রয়োগ করে। "
Gonen I

12

আইডিস্পোজেবলের পরিবর্তে ল্যাম্বডাস ব্যবহার করা।

আমি / IDisposable ধারণা পুরো ব্যবহার করে শিহরিত হয় নি। সমস্যাটি হ'ল এর জন্য কলারের প্রয়োজন:

  • জেনে রাখুন যে তাদের অবশ্যই আইডিস্পোজেবল ব্যবহার করা উচিত
  • ব্যবহার করে মনে রাখবেন।

আমার নতুন পছন্দসই পদ্ধতিটি হ'ল তার পরিবর্তে একটি কারখানা পদ্ধতি এবং ল্যাম্বদা ব্যবহার করা

কল্পনা করুন যে আমি একটি এসকিএলসিএনেকশন (এমন কিছু যা ব্যবহারে মোড়ানো উচিত) দিয়ে কিছু করতে চাই। ধ্রুপদীভাবে আপনি করতে হবে

using (Var conn = Factory.MakeConnection())
{
     conn.Query(....);
}

নতুন উপায়

Factory.DoWithConnection((conn)=>
{
    conn.Query(...);
}

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

DoWithConnication এর মত দেখাচ্ছে looks

void DoWithConnection(Action<SqlConnection> action)
{
   using (var conn = MakeConnection())
   {
       action(conn);
   }
}

MakeConnection এখন ব্যক্তিগত


2
ল্যাম্বডাসে জিনিসপত্র মোড়ানো একটি ভাল পদ্ধতির হতে পারে তবে এর সীমাবদ্ধতা রয়েছে। পরিস্থিতিগুলির পক্ষে এটি খুব খারাপ নয় যেখানে প্রকৃতপক্ষে শ্রেণীর সমস্ত গ্রাহক একটি "ব্যবহার করে" ব্লক নিযুক্ত করবেন তবে এটি এমন পরিস্থিতিতে অস্বীকার করবে যেখানে কোনও পদ্ধতি কোনও শ্রেণীর ক্ষেত্রে একটি আইডিস্পোজেবল সংরক্ষণ করতে পারে (হয় প্রত্যক্ষভাবে বা পুনরুক্তির মতো কিছুতে) )।
সুপারক্যাট

@ সুপের্যাট আপনি যুক্তি দিতে পারেন যে রিসোর্স হগিংয়ের জিনিসগুলি সঞ্চয় করা অস্বীকার করা ভাল জিনিস। আমি এখানে ধার করার মডেলটি উত্সাহিত করেছি আপনাকে আপনার উত্সের ব্যবহারের সাথে ঝুঁকতে বাধ্য করে
ঝুঁকতে বাধ্য বিকাল 100

এটি একটি ভাল জিনিস হতে পারে, তবে এটি কিছু খুব যুক্তিসঙ্গত অপারেশনকেও খুব কঠিন করে তুলতে পারে। উদাহরণস্বরূপ, ধরুন যে কোনও ডাটাবেস-রিডার প্রকারের পরিবর্তে আইনিউবারেবল <T> প্রয়োগ না করে একটি পদ্ধতি উন্মোচিত DoForAll(Action<T>) where T:IComparable<T>করে প্রতিটি রেকর্ডে নির্দেশিত প্রতিনিধিকে কল করে। এই জাতীয় দুটি বস্তু দেওয়া, উভয়ই সাজানো ক্রমে ডেটা ফেরত দেবে, কীভাবে একটি সংগ্রহের মধ্যে থাকা সমস্ত আইটেমকে অন্যভাবে আউটপুট দেয় কীভাবে? যদি প্রকারগুলি প্রয়োগ করা হয় IEnumerable<T>তবে কেউ একটি মার্জিং অপারেশন করতে পারে তবে তা কার্যকর হবে না DoForAll
সুপারক্যাট

আমি DoForAllপ্রথমে একটি সম্পূর্ণ অনুলিপি না করে দুটি সংগ্রহের একত্রীকরণের একমাত্র উপায় , এর সম্পূর্ণরূপে, অন্য কোনও কাঠামোর মধ্যে দুটি থ্রেড ব্যবহার করব, যা কেবলমাত্র কয়েকটি দম্পতি ব্যবহার করা এবং সতর্কতা অবলম্বন করার চেয়ে সংস্থানগুলির চেয়ে আরও বেশি জোগাড় হবে তাদের মুক্তি।
supercat

-1: জিজ্ঞাসা করা হয়নি এমন একটি প্রশ্নের উত্তরের উত্তর। এটি "আমি কীভাবে আইডিজিপোজেবল অবজেক্টগুলিকে সহজে ব্যবহার করতে পারি"
জন স্যান্ডার্স

10

আপনার প্রয়োজন না সত্ত্বেও আপনার আইডিস্পোজেবল বাস্তবায়ন করা উচিত কিনা এই প্রশ্নের উত্তর কেউই দেয়নি।

সংক্ষিপ্ত উত্তর: না

দীর্ঘ উত্তর:

এটি আপনার শ্রেণীর কোনও গ্রাহককে 'ব্যবহার' ব্যবহার করার অনুমতি দেবে। আমি যে প্রশ্নটি জিজ্ঞাসা করব তা হল - তারা এটি করবে কেন? বেশিরভাগ ডেভস 'ব্যবহার' ব্যবহার করবে না যতক্ষণ না তারা জেনে থাকে যে তাদের অবশ্যই - এবং কীভাবে তারা জানে। উভয় ক্ষেত্রেই

  • এটি অভিজ্ঞতা থেকে তাদের আপত্তি জানায় (উদাহরণস্বরূপ একটি সকেট শ্রেণি)
  • এটি নথিভুক্ত
  • তারা সতর্ক এবং ক্লাসটি অযৌক্তিকভাবে প্রয়োগ করে দেখতে পারে

সুতরাং IDisposable বাস্তবায়নের মাধ্যমে আপনি devs (কমপক্ষে কিছু) কে বলছেন যে এই শ্রেণিটি এমন কিছু এমনভাবে জড়িয়ে দেয় যা অবশ্যই মুক্তি দিতে হবে। তারা 'ব্যবহার করে' ব্যবহার করবে - তবে অন্যান্য ক্ষেত্রেও ব্যবহার করা সম্ভব নয় (বস্তুর ক্ষেত্রটি স্থানীয় নয়); এবং তাদের অন্যান্য বিষয়গুলির মধ্যে অবজেক্টগুলির আজীবন সম্পর্কে উদ্বেগ শুরু করতে হবে - আমি অবশ্যই উদ্বিগ্ন হব। তবে এটি প্রয়োজনীয় নয়

আপনি তাদের ব্যবহারে সক্ষম করতে আইডিস্পোজেবলকে বাস্তবায়ন করেন তবে আপনি তাদের না বললে তারা এগুলি ব্যবহার করবে না।

সুতরাং এটি করবেন না


1
আমি বুঝতে পারি না কেন কোনও দেবতা আইডিস্পোজেবল বাস্তবায়নকারী কোনও অবজেক্টে কেন / ডিসপোজ ব্যবহার করবেন না (যদি না প্রোগ্রামটি যেভাবেই বেরিয়ে আসে)।
অ্যাড্রিনিম

1
মুল বক্তব্যটি হ'ল কোনও দেবকে সমস্ত কোড পথগুলিতে নিষ্পত্তি করতে সমস্ত কল লিখতে হবে যার ফলে এটির অনিয়ন্ত্রিত হয়। উদাহরণস্বরূপ, যদি আমি কোনও অভিধানে একটি উদাহরণ রাখি, যখন আমি অভিধান থেকে আমার প্রবেশদ্বার মুছতে হয় তখন আমাকে নিষ্পত্তি করতে হবে। এটি অনেক ঝামেলা যা এই ক্ষেত্রে প্রয়োজন হয় না
অবজেক্টটি

3
@ pm100 লিখেছেন: অযথা IDisposable বাস্তবায়নের - এ বিস্তারিত নিবন্ধ নেই codeproject.com/KB/dotnet/idisposable.aspx যা কিছু বিরল ক্ষেত্রে যখন আপনি এই সম্পর্কে চিন্তা করতে চাইবেন আলোচনা (খুব বিরল, আমি নিশ্চিত)। সংক্ষেপে: আপনি যদি ভবিষ্যতে আইডিস্পোজেবলের প্রয়োজনের বিষয়ে, বা কোনও উত্পন্ন বস্তুতে আগে থেকে ধারণা নিতে পারেন, তবে আপনি কিছু বেসিক অবজেক্টের প্রয়োজন এমন "কাটা" সমস্যা এড়াতে আপনার বেস ক্লাসে আইডিজপোজেবল বাস্তবায়নের বিষয়ে ভাবতে পারেন নিষ্পত্তি এবং অন্যদের না।
কেভিন পি। রাইস

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

  2. আপনার শ্রেণি যদি কোনও দুষ্প্রাপ্য সংস্থান ব্যবহার না করে তবে আপনি কেন আপনার শ্রেণিটিকে অযৌক্তিকভাবে কার্যকর করতে পারবেন তা দেখতে আমি ব্যর্থ। আপনার কেবল তখনই করা উচিত যদি আপনি:

    • জেনে রাখুন আপনার জিনিসগুলিতে খুব শীঘ্রই আপনার অভাবের সংস্থান থাকবে, এখনই নয় (এবং আমি বোঝাতে চাইছি যে "আমরা এখনও বিকাশ করছি, এটি সম্পন্ন হওয়ার আগেই এখানে আসবে"), "আমার মনে হয় আমাদের এটির প্রয়োজন হবে না" ")
    • দুর্লভ সংস্থান ব্যবহার করা
  3. হ্যাঁ, যে কোডটি আপনার কোড ব্যবহার করে সেগুলিকে অবশ্যই আপনার অবজেক্টের নিষ্পত্তি পদ্ধতিতে কল করতে হবে। এবং হ্যাঁ, আপনার অবজেক্ট ব্যবহার করে usingএমন কোডগুলি আপনার প্রদর্শিত হিসাবে ব্যবহার করতে পারে ।

  4. (2 আবার?) সম্ভবত ওয়েবক্লিয়েন্টটি নিয়ন্ত্রণহীন সংস্থানগুলি বা আইডিপোজেবল বাস্তবায়নকারী অন্যান্য পরিচালিত সংস্থান ব্যবহার করে। সঠিক কারণটি অবশ্য গুরুত্বপূর্ণ নয়। গুরুত্বপূর্ণটি হ'ল এটি আইডিস্পোজেবল কার্যকর করে এবং তাই ওয়েবক্লিয়েন্ট অন্য কোনও সংস্থান ব্যবহার না করে এমন কিছুর পরেও যখন আপনি এটি সম্পন্ন করেছেন তখন অবজেক্টটি নিষ্পত্তি করে সেই জ্ঞানের উপর নির্ভর করে আপনার উপর পড়ে।


4

নিষ্পত্তি প্যাটার্ন:

public abstract class DisposableObject : IDisposable
{
    public bool Disposed { get; private set;}      

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

    ~DisposableObject()
    {
        Dispose(false);
    }

    private void Dispose(bool disposing)
    {
        if (!Disposed)
        {
            if (disposing)
            {
                DisposeManagedResources();
            }

            DisposeUnmanagedResources();
            Disposed = true;
        }
    }

    protected virtual void DisposeManagedResources() { }
    protected virtual void DisposeUnmanagedResources() { }
}

উত্তরাধিকারের উদাহরণ:

public class A : DisposableObject
{
    public Component components_a { get; set; }
    private IntPtr handle_a;

    protected override void DisposeManagedResources()
    {
        try
        {
          Console.WriteLine("A_DisposeManagedResources");
          components_a.Dispose();
          components_a = null;
        }
        finally
        { 
          base.DisposeManagedResources();
        }
    }

    protected override void DisposeUnmanagedResources()
    {
        try
        {
          Console.WriteLine("A_DisposeUnmanagedResources");
          CloseHandle(handle_a);
          handle_a = IntPtr.Zero;
        }
        finally
        { 
          base.DisposeUnmanagedResources();
        }
    }
}

public class B : A
{
    public Component components_b { get; set; }
    private IntPtr handle_b;

    protected override void DisposeManagedResources()
    {
        try
        {
          Console.WriteLine("B_DisposeManagedResources");
          components_b.Dispose();
          components_b = null;
        }
        finally
        { 
          base.DisposeManagedResources();
        }
    }

    protected override void DisposeUnmanagedResources()
    {
        try
        {
          Console.WriteLine("B_DisposeUnmanagedResources");
          CloseHandle(handle_b);
          handle_b = IntPtr.Zero;
        }
        finally
        { 
          base.DisposeUnmanagedResources();
        }
    }
}

4

অন্য উত্তরের কিছু দিক 2 কারণে কিছুটা ভুল:

প্রথমত,

using(NoGateway objNoGateway = new NoGateway())

আসলে এর সমতুল্য:

try
{
    NoGateway = new NoGateway();
}
finally
{
    if(NoGateway != null)
    {
        NoGateway.Dispose();
    }
}

এটি হাস্যকর মনে হতে পারে কারণ 'নতুন' অপারেটরটি কখনই 'নাল' ফিরবে না যদি না আপনার কাছে আউটআফমেমরি ব্যতিক্রম থাকে। তবে নিম্নলিখিত কেসগুলি বিবেচনা করুন: ১. আপনি একটি ফ্যাক্টরি ক্লাস কল করেন যা কোনও আইডিস্পোজেবল সংস্থান ফেরত দেয় বা ২। যদি আপনার এমন কোনও ধরণের থাকে যা এর প্রয়োগের উপর নির্ভর করে আইডিস্পোসেবল থেকে উত্তরাধিকারী হতে পারে বা নাও পারে - মনে রাখবেন যে আমি আইডিপোজেবল প্যাটার্নটি ভুলভাবে প্রয়োগ করে দেখেছি অনেকগুলি অনেকগুলি ক্লায়েন্টে এমন সময় যেখানে ডেভেলপাররা আইডিসপোজেবল (খারাপ, খারাপ, খারাপ) এর উত্তরাধিকারসূত্রে ছাড়াই কেবল ডিসপোজ () পদ্ধতি যুক্ত করে। কোনও সম্পত্তি বা পদ্ধতি থেকে কোনও আইডিস্পোজেবল রিসোর্স ফিরিয়ে দেওয়ার ক্ষেত্রেও আপনি থাকতে পারেন (আবার খারাপ, খারাপ, খারাপ - আপনার আইডিস্পোজেবল সংস্থানগুলি দেবেন না)

using(IDisposable objNoGateway = new NoGateway() as IDisposable)
{
    if (NoGateway != null)
    {
        ...

যদি 'হিসাবে' অপারেটর শূন্য ফেরত দেয় (বা সম্পত্তি বা পদ্ধতিটি উত্স ফিরিয়ে দেয়), এবং 'ব্লক' ব্যবহার করে আপনার কোড 'নাল' থেকে রক্ষা করে, কারণ কোনও নাল বস্তুর উপর ডিসপোজ কল করার চেষ্টা করার সময় আপনার কোডটি ফুটে উঠবে না of 'অন্তর্নির্মিত' নাল চেক।

আপনার উত্তরটি সঠিক না হওয়ার দ্বিতীয় কারণটি নিম্নলিখিত স্ট্যাম্টের কারণে:

একটি চূড়ান্তকরণকারীকে জিসি আপনার অবজেক্টটি ধ্বংস করার আহ্বান জানায়

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

আমি আমার ব্লগে ডিসপোজ প্যাটার্নটির একটি সঠিক বাস্তবায়ন পোস্ট করেছি: কীভাবে ডিসপোজ প্যাটার্নটি যথাযথভাবে প্রয়োগ করতে হবে


2
আপনি লেখার বিষয়ে নিশ্চিত এবং NoGateway = new NoGateway();এবং NoGateway != null?
Curur

1
এটি কি স্ট্যাকওভারফ্লো . com/a/898856/3195477 উল্লেখ করছে ? '
আইসিসি

@ ডেভইনকাজ মনে হচ্ছে এটি সঠিক। আমি 'আইসিসি' কোথাও দেখতে পাচ্ছি না তবে আমার প্রতিক্রিয়ার প্রসঙ্গটি আপনার উপরের লিঙ্কের সরবরাহ করা উত্তরে নির্দেশিত বলে মনে হচ্ছে। তিনি কি তার ব্যবহারকারীর নাম পরিবর্তন করেছেন?
ডেভ ব্ল্যাক

@ ডেভ ব্ল্যাক দুর্দান্ত, ধন্যবাদ আমি ঠিক এটি পাঠ্যের মধ্যে সম্পাদনা করেছি।
UuDdLrLrSs

2

1) ওয়েবক্লিয়েন্ট একটি পরিচালিত প্রকার, সুতরাং আপনার চূড়ান্তকরণের দরকার নেই। আপনার ব্যবহারকারীরা আপনার নোগেটওয়ে শ্রেণীর () ডিসপোজ না করে এবং নেটিভ টাইপ (যা জিসি দ্বারা সংগ্রহ করা হয় না) পরে পরিষ্কার করার ক্ষেত্রে ক্ষেত্রে চূড়ান্তকরণের প্রয়োজন। এই ক্ষেত্রে, ব্যবহারকারী যদি ডিসপোজ () কল না করে তবে অন্তর্ভুক্ত ওয়েবক্লিয়েন্টটি নোগেটওয়ের ঠিক পরে জিসি দ্বারা নিষ্পত্তি করা হবে।

2) পরোক্ষভাবে হ্যাঁ, তবে আপনার এটি নিয়ে চিন্তা করা উচিত নয়। আপনার কোডটি স্ট্যান্ড হিসাবে সঠিক এবং আপনি আপনার ব্যবহারকারীদের খুব সহজেই নিষ্পত্তি করতে () ভুলে যাওয়া থেকে আটকাতে পারবেন না।


2

এমএসডিএন থেকে প্যাটার্ন

public class BaseResource: IDisposable
{
   private IntPtr handle;
   private Component Components;
   private bool disposed = false;
   public BaseResource()
   {
   }
   public void Dispose()
   {
      Dispose(true);      
      GC.SuppressFinalize(this);
   }
   protected virtual void Dispose(bool disposing)
   {
      if(!this.disposed)
      {        
         if(disposing)
         {
            Components.Dispose();
         }         
         CloseHandle(handle);
         handle = IntPtr.Zero;
       }
      disposed = true;         
   }
   ~BaseResource()      
   {      Dispose(false);
   }
   public void DoSomething()
   {
      if(this.disposed)
      {
         throw new ObjectDisposedException();
      }
   }
}
public class MyResourceWrapper: BaseResource
{
   private ManagedResource addedManaged;
   private NativeResource addedNative;
   private bool disposed = false;
   public MyResourceWrapper()
   {
   }
   protected override void Dispose(bool disposing)
   {
      if(!this.disposed)
      {
         try
         {
            if(disposing)
            {             
               addedManaged.Dispose();         
            }
            CloseHandle(addedNative);
            this.disposed = true;
         }
         finally
         {
            base.Dispose(disposing);
         }
      }
   }
}

1
using(NoGateway objNoGateway = new NoGateway())

সমতুল্য

try
{
    NoGateway = new NoGateway();
}

finally
{
    NoGateway.Dispose();
}

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


1
কোনও চূড়ান্তকরণকারীকে জিসি অবজেক্টটি ধ্বংস করার আহ্বান জানানো হয় না। যদি "ফাইনালাইজ "টি ওভাররাইড করা হয়, তবে জিসি অন্যথায় যখন বস্তুটি ধ্বংস করে দিত , তখন এটি চূড়ান্তকরণের প্রয়োজনযুক্ত সামগ্রীর একটি সারিতে স্থাপন করা হবে, সাময়িকভাবে এটির জন্য একটি দৃ reference় রেফারেন্স তৈরি করবে এবং - অন্তত অস্থায়ীভাবে -" পুনরুত্থান "করবে।
সুপারক্যাট

-5

আমি যা জানি তা থেকে ফাইনালাইজার / ডেস্ট্রাক্টর ব্যবহার না করার জন্য এটি সুপারিশ করা হয়:

public ~MyClass() {
  //dont use this
}

বেশিরভাগ ক্ষেত্রে, এটি কখন বা আইএফ বলা হবে তা না জানার কারণে। নিষ্পত্তি পদ্ধতিটি আরও ভাল, বিশেষত আপনি যদি আমাদের সরাসরি ব্যবহার করেন বা নিষ্পত্তি করেন।

ব্যবহার করা ভাল। এটা ব্যবহার করো :)


2
আপনার কুকুরের উত্তরের লিঙ্কটি অনুসরণ করা উচিত। হ্যাঁ, ডিসপোজ ব্যবহার / ব্যবহার করা ভাল তবে একটি ডিসপোজযোগ্য শ্রেণীর অবশ্যই উভয় প্রয়োগ করা উচিত।
হেন্ক হলটারম্যান

আকর্ষণীয়, মাইক্রোসফ্ট থেকে আমি সমস্ত দস্তাবেজগুলি পড়েছি - যেমন ফ্রেমওয়ার্ক ডিজাইনের গাইডলাইন - বলুন না যে কোনও ডেস্ট্রাক্টর ব্যবহার করবেন না। সর্বদা আইডিসপোজেবল ব্যবহার করুন।
নিক ওয়াইজ

5
একটি ক্লাস ব্যবহার এবং ক্লাস লেখার মধ্যে পার্থক্য করুন , তাদের আবার পড়ুন।
হেন্ক হলটারম্যান

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