আপডেট : আমি এই প্রশ্নটি এখানে পাওয়া যায় এমন নিবন্ধের ভিত্তি হিসাবে ব্যবহার করেছি ; এই সমস্যাটির অতিরিক্ত আলোচনার জন্য এটি দেখুন। ভাল প্রশ্নের জন্য ধন্যবাদ!
যদিও স্ক্যাবসের উত্তর অবশ্যই সঠিক এবং জিজ্ঞাসিত প্রশ্নের উত্তর দিয়েছে, আপনি আপনার জিজ্ঞাসা করেননি এমন প্রশ্নে একটি গুরুত্বপূর্ণ বৈকল্পিক রয়েছে:
কনস্ট্রাক্টর কর্তৃক অবহেলিত রিসোর্স বরাদ্দের পরে কিন্তু সিটি ফেরার আগে এবং রেফারেন্সটি পূরণ করার আগেfont4 = new Font() নিক্ষেপ করলে কী হবে ?font4
আমাকে এটি আরও কিছুটা পরিষ্কার করুন। ধরুন আমাদের আছে:
public sealed class Foo : IDisposable
{
private int handle = 0;
private bool disposed = false;
public Foo()
{
Blah1();
int x = AllocateResource();
Blah2();
this.handle = x;
Blah3();
}
~Foo()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (this.handle != 0)
DeallocateResource(this.handle);
this.handle = 0;
this.disposed = true;
}
}
}
এখন আমাদের আছে
using(Foo foo = new Foo())
Whatever(foo);
এই হিসাবে একই
{
Foo foo = new Foo();
try
{
Whatever(foo);
}
finally
{
IDisposable d = foo as IDisposable;
if (d != null)
d.Dispose();
}
}
ঠিক আছে. ধরুন, Whateverছুড়ে ফেলেছেন তারপরে finallyব্লকটি সঞ্চালিত হয় এবং সংস্থানটি বাতিল করা হয়। সমস্যা নেই.
ধরুন, Blah1()ছুড়ে ফেলেছেন রিসোর্স বরাদ্দ হওয়ার আগে নিক্ষেপ ঘটে। অবজেক্ট বরাদ্দ করা হয়েছে তবে কর্টারটি আর ফিরে আসে না, তাই fooকখনও পূরণ হয় না We আমরা কখনও প্রবেশ tryকরি নি তাই আমরা কখনও প্রবেশ করি না finally। অবজেক্ট রেফারেন্স এতিম হয়েছে। শেষ পর্যন্ত জিসি এটি আবিষ্কার করবে এবং এটি চূড়ান্তকরণকারী সারিতে রাখবে। handleএখনও শূন্য, তাই চূড়ান্তকারী কিছুই না। লক্ষ্য করুন যে চূড়ান্ত করা হচ্ছে এমন কোনও অবজেক্টের মুখে ফাইনালাইজারটি দৃ rob় হতে হবে যার নির্মাণকারী কখনও শেষ করেনি । তুমি প্রয়োজনীয় finalizers যে এই শক্তিশালী লিখতে। এটি বিশেষজ্ঞের কাছে চূড়ান্ত রচনাকারী লেখা ছেড়ে দেওয়ার এবং এটি নিজে করার চেষ্টা না করার আরও একটি কারণ।
অনুমান করা Blah3() ছুড়ে ফেলেছেন সম্পদ বরাদ্দের পরে নিক্ষেপ ঘটে। তবে আবার fooকখনও পূরণ হয় না, আমরা কখনই প্রবেশ করি না finallyএবং চূড়ান্তকরণকারী থ্রেড দ্বারা বস্তুটি পরিষ্কার হয়ে যায়। এবার হ্যান্ডেলটি শূন্য নয়, এবং ফাইনালাইজারটি এটি পরিষ্কার করে। আবার, চূড়ান্তকরণটি এমন কোনও সামগ্রীতে চলছে যার নির্মাণকারী কখনও সফল হন নি, তবে ফাইনালাইজারটি যাইহোক চালায়। স্পষ্টতই এটি অবশ্যই হবে কারণ এই বারে এটি করার কাজ ছিল।
এখন ধরুন Blah2()নিক্ষেপ রিসোর্স বরাদ্দের পরে কিন্তু আগে ঘটে থ্রো হয় handle পূরণ হয়! আবার, ফাইনালাইজারটি চলবে তবে handleএখনও শূন্য এবং আমরা হ্যান্ডেলটি ফাঁস করি!
এই ফাঁসটি যাতে না ঘটে সে জন্য আপনাকে অত্যন্ত চতুর কোড লিখতে হবে । এখন, আপনার Fontসংস্থার ক্ষেত্রে, হেক কে যত্ন করে? আমরা একটি ফন্ট হ্যান্ডেল ফাঁস, বড় ব্যাপার। তবে যদি আপনি একেবারে ইতিবাচকভাবে প্রয়োজন যে প্রতিটি অপ্রয়োজনীয় রিসোর্স পরিষ্কার করা উচিত ব্যতিক্রমগুলির সময় নির্ধারণ করা যাই হোক না কেন আপনার হাতে আপনার খুব সমস্যা আছে।
সিএলআরকে লক দিয়ে এই সমস্যাটি সমাধান করতে হবে। যেহেতু সি # 4, lockবিবৃতি ব্যবহার করে এমন লকগুলি এভাবে প্রয়োগ করা হয়েছে:
bool lockEntered = false;
object lockObject = whatever;
try
{
Monitor.Enter(lockObject, ref lockEntered);
lock body here
}
finally
{
if (lockEntered) Monitor.Exit(lockObject);
}
Enterখুব সাবধানে যাতে লেখা হয়েছে যে কোন ব্যাপার কি ব্যতিক্রম নিক্ষিপ্ত হয় , lockEnteredসত্যতে সেট করা থাকে যদি এবং কেবল যদি লক আসলে নিয়ে যাওয়া হয়। আপনার যদি অনুরূপ প্রয়োজনীয়তা থাকে তবে আপনাকে যা লিখতে হবে তা আসলে লিখুন:
public Foo()
{
Blah1();
AllocateResource(ref handle);
Blah2();
Blah3();
}
এবং লিখতে AllocateResourceচালাকি করে মত Monitor.Enterতাই কোন ব্যাপার কি ভিতরে ঘটে যে AllocateResource, handleএ ভরা হয় যদি এবং কেবল যদি এটা deallocated করা প্রয়োজন।
এটি করার কৌশলগুলি বর্ণনা করা এই উত্তরের সুযোগের বাইরে। আপনার যদি এই প্রয়োজনীয়তা থাকে তবে একজন বিশেষজ্ঞের সাথে পরামর্শ করুন।