বনাম নিষ্পত্তি চূড়ান্ত করুন


215

কিছু লোক কেন এই Finalizeপদ্ধতিতে পদ্ধতিটি ব্যবহার করে Dispose?

কোন পরিস্থিতিতে আপনি পদ্ধতিটি এবং তার বিপরীতে Finalizeপদ্ধতিটি ব্যবহার করবেন Dispose?


উত্তর:


121

অন্যরা ইতিমধ্যে Disposeএবং এর মধ্যে পার্থক্যটি Finalize.েকে ফেলেছে (বিটিডব্লিউ Finalizeপদ্ধতিটিকে এখনও ভাষা স্পেসিফিকেশনে ডেস্ট্রাক্টর বলা হয়), সুতরাং আমি যে পরিস্থিতিটি কার্যকর হবে সেই পরিস্থিতিগুলি সম্পর্কে আমি কিছুটা যুক্ত করব Finalize

কিছু প্রকার ডিসপোজেবল সংস্থানগুলিকে এমনভাবে আবদ্ধ করে যেখানে একক ক্রিয়ায় সেগুলি ব্যবহার করা এবং নিষ্পত্তি করা সহজ। সাধারণ ব্যবহার প্রায়শই এর মতো: খোলা, পড়ুন বা লিখুন, বন্ধ করুন (নিষ্পত্তি করুন)। এটি usingনির্মাণের সাথে খুব ভাল ফিট করে ।

অন্যরা কিছুটা বেশি কঠিন। WaitEventHandlesউদাহরণস্বরূপ এগুলি ব্যবহার করা হয় না কারণ এগুলি এক থ্রেড থেকে অন্য থ্রেডে সিগন্যাল করতে ব্যবহৃত হয়। প্রশ্নটি তখন হয়ে ওঠে কার এগুলিতে ডাকা উচিত Dispose? এগুলির মতো সুরক্ষার ধরণগুলি একটি Finalizeপদ্ধতি প্রয়োগ করে , যা নিশ্চিত করে যে সংস্থাগুলি যখন আর অ্যাপ্লিকেশন দ্বারা রেফারেন্স করা হয় না তখন সংস্থানগুলি নিষ্পত্তি হয়।


60
আমি এই অনুমোদিত উত্তরটি বুঝতে পারি না। আমি এখনও আলাদা জানতে চাই। এটা কি?
ইসমাইল

22
@ ইসমাইল: Finalizeন্যায্যতম হতে পারে এমন বৃহত্তম পরিস্থিতিটি তখন যখন এমন সংখ্যক অবজেক্ট থাকে যা সম্পদকে বাঁচিয়ে রাখতে আগ্রহী, তবে এর কোনও উপায় নেই যার সাহায্যে উত্সটিতে আগ্রহী হওয়া কোনও বস্তু এটি আবিষ্কার করতে পারে কিনা সর্বশেষ. এই ক্ষেত্রে, Finalizeসাধারণত তখনই গুলি চালানো হবে যখন কেউ বস্তুর প্রতি আগ্রহী নয়। Finalizeফাইল এবং লকগুলির মতো অ-ছত্রাকযুক্ত সম্পদের জন্য আলগা সময়টি ভয়াবহ, তবে ছত্রাকযুক্ত সংস্থানগুলির জন্য এটি ঠিক হতে পারে।
সুপারক্যাট

13
দুর্দান্ত 1 (আমার কাছে) শব্দের জন্য সুপারক্যাট থেকে +1 প্রসঙ্গটি এটি বেশ স্পষ্ট করে তুলেছিল, তবে কেবল আমাদের বাকী ক্ষেত্রে উইকিপিডিয়া যা বলেছে তা এখানে রয়েছে: "ছদ্মবেশিতা হ'ল একটি ভাল বা একটি সামগ্রীর সম্পত্তি যার পৃথক ইউনিট পারস্পরিক প্রতিস্থাপনে সক্ষম, যেমন মিষ্টি অপরিশোধিত তেলের অংশীদারিত্ব একটি সংস্থা, বন্ড, মূল্যবান ধাতু বা মুদ্রা।
জন Coombs

5
@JonCoombs: তা প্রায় কাছাকাছি ঠিক, যদিও এটা লক্ষণীয় যে, শব্দ "fungible রিসোর্স" যা স্বাধীনভাবে substitutable হয় প্রয়োগ করা হয় মূল্য হতে পারে যতক্ষণ না তারা অর্জিত হয় এবং আবার অবাধে substitutable হয়ে মুক্তি বা বিসর্জন পর । সিস্টেমে যদি কোনও লক অবজেক্টের পুল থাকে এবং কোডটি কোনও সত্তার সাথে এটি যুক্ত করে, তবে যতক্ষণ না কেউ এই সত্তার সাথে সম্পর্কিত হওয়ার উদ্দেশ্যে সেই লকটির কোনও রেফারেন্স ধরে রাখে , সেই লকটি তার সাথে প্রতিস্থাপিত নাও হতে পারে অন্য কেউ. সুরক্ষিত সত্তা সম্পর্কে যত্নশীল সমস্ত কোড যদি লকটি ছেড়ে দেয় তবে ...
সুপারক্যাট

... তবে এটি অন্য কোনও সত্তার সাথে সম্পর্কিত না হওয়া পর্যন্ত এটি আবার অবাধে পরিবর্তনযোগ্য হয়ে উঠবে।
সুপারক্যাট

135

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

Disposeঅন্যদিকে পদ্ধতি কোডটি আপনার বর্গ নির্মিত যাতে আপনি পরিষ্কার এবং কোন সম্পদগুলি (অপরিচালিত তথ্য, ডাটাবেজ কানেকশন, ফাইল হ্যান্ডলগুলি, ইত্যাদি) মুহূর্ত কোড সহ সম্পন্ন করা হয় তোমরা অর্জন করেছ মুক্তি পারে বলা যেতে বোঝানো হয় আপনার অবজেক্ট

স্ট্যান্ডার্ড অনুশীলনটি বাস্তবায়ন করা IDisposableএবং Disposeযাতে আপনি কোনও usingস্ট্যাটমেন্টে আপনার অবজেক্টটি ব্যবহার করতে পারেন । যেমন using(var foo = new MyObject()) { }। এবং আপনার ফাইনালাইজারে, আপনি কল করেন Dispose, কেবলমাত্র যদি কলিং কোডটি আপনাকে নিষ্পত্তি করতে ভুলে যায়।


17
আপনার চূড়ান্তকরণ বাস্তবায়ন থেকে ডিসপোজ কল করার বিষয়ে আপনাকে কিছুটা সতর্কতা অবলম্বন করা উচিত - নিষ্পত্তি করা পরিচালিত সংস্থানগুলিও নিষ্পত্তি করতে পারে, যা আপনি নিজের ফাইনালাইজারের কাছ থেকে স্পর্শ করতে চান না, কারণ তারা ইতিমধ্যে নিজেরাই চূড়ান্ত হয়ে গেছে।
itowlson

6
@ আইটলসন: নালগুলির জন্য পরীক্ষা করা এই ধারণার সাথে মিলিয়ে যে বস্তুর দ্বিগুণ নিষ্পত্তি করা যায় (দ্বিতীয় কল সহ কিছুই করা যায় না) যথেষ্ট ভাল হওয়া উচিত।
স্যামুয়েল

7
আদর্শ আইডিসপজাল প্যাটার্ন এবং নিষ্পত্তি ব্যবস্থাপনাগুলি componentsচ্ছিকভাবে পরিচালনা করার জন্য ডিসপোজ (বুল) এর লুকানো বাস্তবায়ন এই সমস্যার সমাধান করে বলে মনে হচ্ছে।
ব্রোডি

দেখে মনে হচ্ছে ডিস্ট্রাক্টর (~ মাইক্লাস () পদ্ধতি) প্রয়োগ করার পরিবর্তে আর সবসময় ডিসপোজ () পদ্ধতি প্রয়োগ ও কল করার কোনও কারণ নেই। নাকি আমি ভুল করছি? উভয় বাস্তবায়ন করা উচিত যখন কেউ আমাকে উদাহরণ দিতে পারে?
dpelisek

66

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

কোনও বস্তুর ব্যবহারকারী হিসাবে আপনি সর্বদা ডিসপোজ ব্যবহার করেন। চূড়ান্তকরণ জিসির পক্ষে।

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



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

2
@ জে.কুমবস: Disposeভাল, এবং এটিকে সঠিকভাবে প্রয়োগ করা সাধারণত সহজ। Finalizeমন্দ, এবং এটি সঠিকভাবে প্রয়োগ করা সাধারণত কঠিন। অন্যান্য জিনিসের মধ্যে, কারণ জিসি নিশ্চিত করবে যে কোনও বস্তুর পরিচয় কখনই "পুনর্ব্যবহৃত" পাবে না যতক্ষণ না that অবজেক্টের কোনও রেফারেন্স উপস্থিত থাকে, Disposableঅবজেক্টগুলির একটি গুচ্ছ পরিষ্কার করা সহজ , যার মধ্যে কিছু ইতিমধ্যে পরিষ্কার হয়ে গেছে, এটি সমস্যা নেই; একটি বস্তু কোনো রেফারেন্স যার উপর Disposeইতিমধ্যে বলা হয়েছে একটি বস্তু যার উপর একটি রেফারেন্স থাকবে Disposeইতিমধ্যে বলা হয়েছে।
সুপারক্যাট

2
@ জে.কুমবস: বিপরীতে, নিয়ন্ত্রিত সংস্থাগুলির সাধারণত এর কোনও গ্যারান্টি নেই। যদি অবজেক্টটি Fredফাইল হ্যান্ডেল # 42 এর মালিক এবং এটি বন্ধ করে দেয় তবে সিস্টেমটি একই নম্বরটি ফাইল হ্যান্ডেলের সাথে সংযুক্ত করতে পারে যা অন্য কোনও সত্তাকে দেওয়া হয়। সেক্ষেত্রে, ফাইল হ্যান্ডেল # 42 ফ্রেডের বন্ধ হওয়া ফাইলটিকে বোঝায় না, তবে সেই ফাইলটির জন্য যা অন্য সত্তার সক্রিয় ব্যবহারে ছিল; জন্য Fredপাসে # 42 হাতল চেষ্টা আবার বিপর্যয়মূলক হবে। ১০০% নির্ভরযোগ্যতার সাথে চেষ্টা করা একটি অব্যবহৃত অবজেক্টটি এখনও মুক্তি পেয়েছে কি না তা ট্র্যাক করে রাখার চেষ্টা করে। একাধিক অবজেক্টের ট্র্যাক রাখার চেষ্টা করা আরও শক্ত।
সুপারক্যাট

2
@ জে.কুমবস: যদি প্রতিটি পরিচালনা না করা সংস্থানটি যদি তার নিজস্ব র‌্যাপারে স্থাপন করা হয় যা তার জীবনকাল নিয়ন্ত্রণ করে তবে কিছুই না, তবে বাইরের কোড যা জানে না যে উত্সটি প্রকাশ হয়েছে কিনা, তবে জানে যে এটি হওয়া উচিত যদি এটি ইতিমধ্যে না হয়ে থাকে , মোড়ককে নিরাপদে এটি ছেড়ে দিতে অনুরোধ করতে পারে; মোড়ক বস্তুটি এটি করেছে কিনা তা জানতে পারবে এবং অনুরোধটি সম্পাদন করতে বা উপেক্ষা করতে পারে can জিসি গ্যারান্টি দেয় যে মোড়কের একটি রেফারেন্স সর্বদা মোড়কের ক্ষেত্রে বৈধ রেফারেন্স হয়ে উঠবে এটি একটি খুব দরকারী গ্যারান্টি।
সুপারক্যাট

43

পাকা করা

  • ফাইনালাইজারগুলি সর্বদা হওয়া উচিত protected, না হয় publicবা privateযাতে পদ্ধতিটি সরাসরি এবং একই সাথে আবেদনের কোড থেকে কল করা যায় না, এটি base.Finalizeপদ্ধতিতে একটি কল করতে পারে
  • চূড়ান্তকরণকারীদের কেবল নিয়ন্ত্রণহীন সংস্থানগুলি মুক্তি দেওয়া উচিত।
  • ফ্রেমওয়ার্কটি কোনও গ্যারান্টি দেয় না যে কোনও চূড়ান্তকরণের কোনও নির্দিষ্ট পরিস্থিতিতে কার্যকর করা হবে।
  • চূড়ান্তকরণকারীগুলিতে কখনও মেমরি বরাদ্দ করবেন না বা চূড়ান্তকারীদের কাছ থেকে ভার্চুয়াল পদ্ধতিগুলি কল করুন।
  • চূড়ান্তকরণকারীগুলিতে সিঙ্ক্রোনাইজেশন এবং আনহ্যান্ডেল ব্যতিক্রম উত্থাপন এড়িয়ে চলুন।
  • চূড়ান্তকরণকারীদের কার্যকর করার আদেশটি অ-নিরঙ্কুশক other অন্য কথায়, আপনি এখনও নিজের চূড়ান্তকরণকারীর মধ্যে উপলব্ধ অন্য কোনও জিনিসের উপর নির্ভর করতে পারবেন না।
  • মান ধরণের উপর চূড়ান্তকারী সংজ্ঞায়িত করবেন না।
  • খালি ধ্বংসকারী তৈরি করবেন না Don't অন্য কথায়, আপনার শ্রেণিটি নিয়ন্ত্রণহীন সংস্থানগুলি পরিষ্কার করার প্রয়োজন না হলে আপনি কোনও স্পষ্টরূপে কোনও ডেস্ট্রাক্টরকে সংজ্ঞায়িত করতে পারবেন না এবং যদি আপনি কোনও সংজ্ঞা দেন তবে এটি কিছু কাজ করা উচিত should যদি, পরে, আপনাকে আর ডাস্ট্রেক্টরটিতে পরিচালনা না করা রিসোর্সগুলি পরিষ্কার করার দরকার নেই, এটি পুরোপুরি সরিয়ে ফেলুন।

মীমাংসা করা

  • IDisposableচূড়ান্তকরণকারী প্রতিটি প্রকারে প্রয়োগ করুন
  • Disposeপদ্ধতিতে কল করার পরে কোনও বস্তু অকেজো হয়ে গেছে তা নিশ্চিত করুন । অন্য কথায়, কোনও Disposeপদ্ধতিতে कॉल করার পরে কোনও বস্তু ব্যবহার করা এড়ানো উচিত।
  • একবার আপনার সাথে সম্পন্ন হয়ে গেলে Disposeসমস্ত IDisposableধরণের কল করুন
  • Disposeত্রুটি না বাড়িয়ে একাধিকবার কল করার অনুমতি দিন ।
  • Disposeপদ্ধতিটি ব্যবহার করে GC.SuppressFinalizeপদ্ধতিটির মধ্যে থেকে চূড়ান্তভাবে চূড়ান্ত কল করুন
  • ডিসপোজেবল মান প্রকার তৈরি করা এড়িয়ে চলুন
  • Disposeপদ্ধতির মধ্যে থেকে ব্যতিক্রম ছোঁড়া এড়িয়ে চলুন

নিষ্পত্তি / চূড়ান্ত প্যাটার্ন

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

17
আমি এই উত্তরটি সর্বত্রই পড়েছি এবং এখনও প্রত্যেকের উদ্দেশ্য কী তা আমি বুঝতে পারি না। আমি কেবল নিয়মের পরে নিয়ম পড়ি, এর চেয়ে বেশি কিছু নয়।
ইসমাইল

@ ইসমাইল: এবং লেখক এমএসডিএন থেকে কিছু পাঠ্য অনুলিপি এবং আটকানো ছাড়া কিছুই যুক্ত করেন না।
তারিক

@ তারিক আমি এটি ইতিমধ্যে শিখেছি। আমি যখন জিজ্ঞাসা করেছি তখন আমার "প্রতিশ্রুতি" ধারণা ছিল।
ইসমাইল

31

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

নিষ্পত্তি হ'ল একটি সাধারণ পদ্ধতি যা এই শ্রেণীর ব্যবহারকারী যে কোনও সংস্থান ছেড়ে দিতে কল করতে পারে।

ব্যবহারকারী যদি ডিসপোজ কল করতে ভুলে যান এবং যদি ক্লাসটি চূড়ান্ত রূপায়ণ করে থাকে তবে জিসি নিশ্চিত হয় যে এটি কল হয়েছে।


3
সর্বকালের সবচেয়ে পরিষ্কার উত্তর
ডেরিওগ্রিফো

19

এমসিএসডি সার্টিফিকেশন টুলকিট (পরীক্ষা 70-483) পৃষ্ঠা 193 বইটি সম্পর্কে কিছু কী রয়েছে:

ডেস্ট্রাক্টর ≈ (এটি প্রায় সমান)base.Finalize() , ডেস্ট্রাক্টর ফাইনালাইজ পদ্ধতির একটি ওভাররাইড সংস্করণে রূপান্তরিত হয় যা ডিস্ট্রাক্টরের কোড কার্যকর করে এবং তারপরে বেস শ্রেণীর ফাইনালাইজ পদ্ধতিটিকে কল করে। তারপরে এটি সম্পূর্ণরূপে অবিচ্ছিন্ন আপনি জেনে নিতে পারবেন না কখন ডাকা হবে কারণ এটি জিসির উপর নির্ভর করে।

যদি কোনও শ্রেণীর কোনও পরিচালিত সংস্থান থাকে এবং কোনও পরিচালনা না করা সংস্থান থাকে , তবে এটি কার্যকর করা IDisposableবা ধ্বংসকারী থাকতে হবে না should

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

শ্রেণীরIDisposable যদি কেবল পরিচালনা ব্যবস্থা নেই, প্রোগ্রামটি কল না করার ক্ষেত্রে এটি প্রয়োগ করা প্রয়োজন এবং একজন ডেস্ট্রাক্টর প্রয়োজন Dispose()

Dispose()পদ্ধতিটি একাধিকবার চালানোর জন্য নিরাপদ থাকতে হবে। এটি আগে চালিত হয়েছে কিনা তা ট্র্যাক রাখতে আপনি একটি ভেরিয়েবল ব্যবহার করে এটি অর্জন করতে পারেন।

Dispose()পরিচালিত এবং নিয়ন্ত্রণহীন উভয় সংস্থানই মুক্ত করা উচিত

ডেস্ট্রাক্টরকে কেবল নিয়ন্ত্রণহীন সংস্থানগুলি মুক্ত করা উচিত । যখন ডেস্ট্রাক্টর এক্সিকিউট করে, আপনি নিশ্চিত হতে পারবেন না যে পরিচালিত অবজেক্টগুলি এখনও রয়েছে, সুতরাং আপনি তাদের ডিসপোজ পদ্ধতিগুলিকে যেভাবেই কল করতে পারবেন না। এটি ক্যানোনিকাল protected void Dispose(bool disposing)প্যাটার্ন ব্যবহার করে প্রাপ্ত হয় , যেখানে কেবল পরিচালিত সংস্থানগুলি মুক্ত হয় (নিষ্পত্তি হয়) যখন disposing == true

সংস্থানগুলি মুক্ত করার পরে, Dispose()কল করা উচিতGC.SuppressFinalize , যাতে অবজেক্টটি চূড়ান্তকরণের সারিটি এড়িয়ে যেতে পারে।

পরিচালনাহীন এবং পরিচালিত সংস্থানসমূহ সহ একটি শ্রেণীর জন্য বাস্তবায়নের একটি উদাহরণ:

using System;

class DisposableClass : IDisposable
{
    // A name to keep track of the object.
    public string Name = "";

    // Free managed and unmanaged resources.
    public void Dispose()
    {
        FreeResources(true);

        // We don't need the destructor because
        // our resources are already freed.
        GC.SuppressFinalize(this);
    }

    // Destructor to clean up unmanaged resources
    // but not managed resources.
    ~DisposableClass()
    {
        FreeResources(false);
    }

    // Keep track if whether resources are already freed.
    private bool ResourcesAreFreed = false;

    // Free resources.
    private void FreeResources(bool freeManagedResources)
    {
        Console.WriteLine(Name + ": FreeResources");
        if (!ResourcesAreFreed)
        {
            // Dispose of managed resources if appropriate.
            if (freeManagedResources)
            {
                // Dispose of managed resources here.
                Console.WriteLine(Name + ": Dispose of managed resources");
            }

            // Dispose of unmanaged resources here.
            Console.WriteLine(Name + ": Dispose of unmanaged resources");

            // Remember that we have disposed of resources.
            ResourcesAreFreed = true;
        }
    }
}

2
এটি একটি দুর্দান্ত উত্তর! তবে আমি মনে করি এটি ভুল: "ডেস্ট্রাক্টরকে জিসি.সপ্রেসফাইনালাইজ করা উচিত"। পরিবর্তে, পাবলিক ডিসপোজ () পদ্ধতিটি কি GC.SuppressFinalize কল করা উচিত নয়? দেখুন: ডকস.মাইক্রোসফট.ইন- ইউএস / ডটনেট / এপি /… এই পদ্ধতিটি কল করা আবর্জনা সংগ্রহকারীকে অবজেক্ট কল করতে বাধা দেয় inal ফিনালাইজ (যা ধ্বংসকারী দ্বারা উপেক্ষা করা হয়)।
ইভা

7

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

আবর্জনা সংগ্রহের বিষয় সম্পর্কে আরও অনেক কিছু জানার আছে , তবে এটি একটি শুরু।


5
আপনি কোথায়: আমি প্রায় নিশ্চিত C # এর অ্যাপ্লিকেশন তুলনায় আরো 1% ডাটাবেস ব্যবহার করছি আছে IDisposable এসকিউএল কাপড় সম্পর্কে চিন্তা করতে।
স্যামুয়েল

1
এছাড়াও, আপনি যদি আইডিস্পোজেবলগুলি encapsulate করেন তবে আপনার আইডিজিপোজেবল বাস্তবায়ন করা উচিত। যা সম্ভবত অন্যান্য 1% কভার করে।
ড্যারেন ক্লার্ক

@ সামুয়েল: ডেটাবেসগুলি এর সাথে কী করবে তা আমি দেখতে পাচ্ছি না। আপনি যদি কানেকশন বন্ধ করার কথা বলছেন তবে তা ঠিক আছে তবে এটি আলাদা বিষয়। সময় মতো সংযোগ বন্ধ করতে আপনাকে অবজেক্টগুলি নিষ্পত্তি করতে হবে না।
জেপি আলিওটো

1
@ জেপি: তবে ব্যবহারের (...) প্যাটার্নটি এটিকে মোকাবেলা করা এত সহজ করে তুলেছে।
ব্রোডি

2
সম্মত, কিন্তু ঠিক ঠিক এটি। ব্যবহারের ধরণটি আপনার জন্য ডিসপোজ করার জন্য কলটি আড়াল করে।
জেপি আলিওটো

6

চূড়ান্তকরণটি অন্তর্নিহিত পরিষ্কারের জন্য - আপনি যখনই কোনও শ্রেণি এমন সংস্থান পরিচালনা করে যা আপনার অবশ্যই হ্যান্ডলস / মেমরি ইত্যাদি ফাঁস করে দেবে অবশ্যই এটি পরিষ্কার করা উচিত ...

একটি ফাইনালাইজারকে সঠিকভাবে বাস্তবায়ন করা কুখ্যাতভাবে কঠিন এবং যেখানেই সম্ভব এড়ানো উচিত - SafeHandleক্লাস (। নেট ভি ২.০ এবং এর উপরে উপরে) এখন বোঝা যাচ্ছে যে আপনার খুব কমই (যদি কখনও হয়) আর কোনও ফাইনালাইজার প্রয়োগ করা প্রয়োজন।

IDisposableইন্টারফেস স্পষ্ট পরিষ্করণ জন্য এবং আরো অনেক কিছু সাধারণভাবে ব্যবহৃত হয় - আপনি এই ব্যবহার করা উচিত ব্যবহারকারীদের স্পষ্টভাবে মুক্তি বা পরিষ্করণ সম্পদ যখনই একটি বস্তু ব্যবহার শেষ করার সুযোগ দিয়েছে।

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

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


3

সংক্ষিপ্তসারটি হ'ল -

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

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

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

class ClassWithDisposeAndFinalize : IDisposable
{
    // Used to determine if Dispose() has already been called, so that the finalizer
    // knows if it needs to clean up unmanaged resources.
     private bool disposed = false;

     public void Dispose()
     {
       // Call our shared helper method.
       // Specifying "true" signifies that the object user triggered the cleanup.
          CleanUp(true);

       // Now suppress finalization to make sure that the Finalize method 
       // doesn't attempt to clean up unmanaged resources.
          GC.SuppressFinalize(this);
     }
     private void CleanUp(bool disposing)
     {
        // Be sure we have not already been disposed!
        if (!this.disposed)
        {
             // If disposing equals true i.e. if disposed explicitly, dispose all 
             // managed resources.
            if (disposing)
            {
             // Dispose managed resources.
            }
             // Clean up unmanaged resources here.
        }
        disposed = true;
      }

      // the below is called the destructor or Finalizer
     ~ClassWithDisposeAndFinalize()
     {
        // Call our shared helper method.
        // Specifying "false" signifies that the GC triggered the cleanup.
        CleanUp(false);
     }

2

আমি জানি যা সেরা উদাহরণ।

 public abstract class DisposableType: IDisposable
  {
    bool disposed = false;

    ~DisposableType()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(false);
      }
    }

    public void Dispose()
    {
      if (!disposed) 
      {
        disposed = true;
        Dispose(true);
        GC.SuppressFinalize(this);
      }
    }

    public void Close()
    {
      Dispose();
    }

    protected virtual void Dispose(bool disposing)
    {
      if (disposing) 
      {
        // managed objects
      }
      // unmanaged objects and resources
    }
  }

2

সি # তে চূড়ান্তকরণ এবং নিষ্পত্তি পদ্ধতির মধ্যে পার্থক্য।

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

নিষ্পত্তি পদ্ধতি: কোড থেকে কল করার সাথে সাথে আমাদের এটিতে নিম্ন স্তরের নিয়ন্ত্রণ রয়েছে। যখনই আমরা অনুভব করি যে এটি ব্যবহারযোগ্য নয় we আমরা আইডিসপজাল প্যাটার্ন প্রয়োগ করে এটি অর্জন করতে পারি un


1

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

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


1

নিষ্পত্তি এবং চূড়ান্তকরণের মধ্যে প্রধান পার্থক্য হ'ল:

Disposeসাধারণত আপনার কোড দ্বারা কল করা হয়। আপনি যখন ফোন করবেন তখন সংস্থানগুলি তাত্ক্ষণিকভাবে মুক্ত হয়ে যায়। লোকেরা পদ্ধতিটি কল করতে ভুলে যায়, তাই using() {}বিবৃতি উদ্ভাবিত হয়। যখন আপনার প্রোগ্রামটি কোডের অভ্যন্তরে কোডটির সম্পাদন শেষ করে {}, তখন এটি Disposeস্বয়ংক্রিয়ভাবে পদ্ধতিটিকে কল করবে ।

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

আমি ব্যক্তিগতভাবে ডিসপোজে সর্বনাশের যুক্তিটি লিখতাম। আশা করি, এটি বিভ্রান্তি দূর করে।


-1

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


নিষ্পত্তি তাত্ক্ষণিকভাবে সম্পদকে মুক্ত করে es চূড়ান্তকরণ কোনও সময় সময়সীমার সাথে সংস্থানটি মুক্ত বা নাও করতে পারে।
সুপারক্যাট

1
আহ, তার সম্ভবত এই অর্থ হ'ল "একটি চূড়ান্তকরণযোগ্য বস্তুর জিসির
২০১/0

-4

প্রথম অংশে উত্তর দেওয়ার জন্য আপনার উদাহরণ দেওয়া উচিত যেখানে লোকেরা একই শ্রেণি-অবজেক্টের জন্য বিভিন্ন পদ্ধতির ব্যবহার করে। অন্যথায় উত্তর দেওয়া কঠিন (বা এমনকি আজব) is

দ্বিতীয় প্রশ্ন হিসাবে ভাল প্রথম এই পড়া IDisposable ইন্টারফেসের সঠিক ব্যবহার যা দাবী করে

এটা তোমার পছন্দ! তবে ডিসপোজ বেছে নিন।

অন্য কথায়: জিসি কেবল ফাইনালাইজার সম্পর্কে জানে (যদি থাকে তবে মাইক্রোসফ্টের ডেস্ট্রাক্টর হিসাবেও পরিচিত)। একটি ভাল কোড উভয় (চূড়ান্তকরণকারী এবং নিষ্পত্তি) থেকে পরিষ্কার করার চেষ্টা করবে।

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