আবর্জনা সংগ্রাহক কি আইডিস্পোজেবলকে কল করবেন? আমার পক্ষে প্রশ্ন করুন?


134

.NET IDisposable প্যাটার্নটি বোঝায় যে আপনি যদি একটি চূড়ান্ত লেখক লিখেন এবং IDisposable প্রয়োগ করেন তবে আপনার চূড়ান্তকরণকারীকে স্পষ্টতই ডিসপোজ কল করতে হবে। এটি যৌক্তিক, এবং আমি সর্বদা বিরল পরিস্থিতিতে যেখানে ফাইনালাইজারকে সতর্ক করা হয় তা করতে পেরেছি।

তবে, আমি কেবল এটি করলে কী হয়:

class Foo : IDisposable
{
     public void Dispose(){ CloseSomeHandle(); }
}

এবং একটি চূড়ান্তকরণকারী, বা কিছুই বাস্তবায়ন করবেন না। ফ্রেমওয়ার্কটি কি আমার জন্য ডিসপোজ পদ্ধতি কল করবে?

হ্যাঁ আমি বুঝতে পারি যে এই শব্দটি বোবা লাগছে, এবং সমস্ত যুক্তি থেকেই বোঝা যাচ্ছে যে এটি হবে না, তবে আমার মাথার পিছনে সবসময় আমার 2 টি জিনিস ছিল যা আমাকে নিশ্চিত করে না।

  1. কয়েক বছর আগে কেউ একবার আমাকে বলেছিল যে এটি আসলে এটি করবে এবং সেই ব্যক্তির "তাদের জিনিসগুলি জানার" একটি খুব দৃ track় ট্র্যাক রেকর্ড রয়েছে।

  2. সংকলক / কাঠামোটি অন্যান্য 'ম্যাজিক' জিনিসগুলি নির্ভর করে আপনি কী ইন্টারফেস প্রয়োগ করেন তার উপর নির্ভর করে (যেমন: ফোরচ, এক্সটেনশন পদ্ধতি, বৈশিষ্ট্যের উপর ভিত্তি করে সিরিয়ালাইজেশন ইত্যাদি), সুতরাং এটি বোঝা যায় যে এটি 'ম্যাজিক'ও হতে পারে।

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

উত্তর:


121

। নেট আবর্জনা সংগ্রাহক আবর্জনা কল করে garbage দ্বারা ডিফল্ট এই আছে কিছুই এবং overidden হতে হবে যদি আপনি অতিরিক্ত সম্পদ মুক্ত করতে চাই।

নিষ্পত্তি স্বয়ংক্রিয়ভাবে কল করা হয় না এবং উত্সগুলি প্রকাশ করতে হলে অবশ্যই স্পষ্টতা বলা উচিত , যেমন একটি 'ব্যবহার' বা 'শেষ অবধি চেষ্টা করুন' ব্লকের মধ্যে

দেখতে http://msdn.microsoft.com/en-us/library/system.object.finalize.aspx আরও তথ্যের জন্য


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

7
দুটিই MSDN অনুযায়ী: msdn.microsoft.com/en-us/library/... তুমি কি আসলে "ওভাররাইড" C # Object.Finalize পদ্ধতি, কম্পাইলার একটি ত্রুটি উত্পন্ন করতে পারেন: দো object.Finalize ওভাররাইড করতে। পরিবর্তে, একটি ধ্বংসকারী সরবরাহ করুন। ; অর্থাৎ আপনাকে অবশ্যই এমন একজন ডেস্ট্রাক্টর কার্যকর করতে হবে যা কার্যকরভাবে ফাইনালাইজার হিসাবে কাজ করে acts [কেবলমাত্র এখানে সম্পূর্ণতার জন্য যুক্ত করা হয়েছে কারণ এটি গৃহীত উত্তর এবং সম্ভবত পড়ার সম্ভাবনা]
সুধাংশু মিশ্র

1
জিসি কোনও চূড়ান্তকরণকারীকে ওভাররাইড করে না এমন কোনও বস্তুর সাথে কিছুই করে না। এটি চূড়ান্তকরণের সারিতে রাখা হয়নি - এবং কোনও ফাইনালাইজার বলা হয় না।
ডেভ ব্ল্যাক

1
@ ডটনেটগুয়ে - যদিও মূল সি # অনুমান একটি "ডিস্ট্রাক্টর" হিসাবে উল্লেখ করেছে তবে এটিকে আসলে একটি ফাইনালাইজার বলা হয় - এবং প্রকৃত "ডেস্ট্রাক্টর" কীভাবে পরিচালনা না করা ভাষার জন্য কাজ করে তার তুলনায় এর যান্ত্রিকতা সম্পূর্ণ আলাদা different
ডেভ ব্ল্যাক

67

আমি তার মন্তব্যে ব্রায়ানের বক্তব্যকে জোর দিতে চাই, কারণ এটি গুরুত্বপূর্ণ।

ফাইনালাইজাররা সি ++ এর মতো ডিটারমিনিস্টিক ডেস্ট্রাস্টার নয়। অন্যদের নির্দিষ্ট আছে, যখন এটি বলা হবে কোন গ্যারান্টি, এবং প্রকৃতপক্ষে যদি আপনি পর্যাপ্ত মেমরি আছে, যদি হবে কি কখনো বলা হবে।

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

আপনি যেমন জানেন বা নাও জানেন, জিসি প্রজন্মগুলিতে বিভক্ত হয় - জেনারেল 0, 1 এবং 2, এবং বৃহত্তর অবজেক্ট হিপ। বিভক্ত একটি আলগা শব্দ - আপনি মেমরির একটি ব্লক পান তবে জেনার 0 টি অবজেক্ট শুরু এবং শেষ হয় এমন পয়েন্টার রয়েছে।

চিন্তার প্রক্রিয়াটি হ'ল আপনি সম্ভবত প্রচুর পরিমাণে অবজেক্ট ব্যবহার করবেন যা স্বল্পস্থায়ী হবে। সুতরাং এগুলি জিসি - জেনারেল 0 টি অবজেক্টে পাওয়া সহজ এবং দ্রুত হওয়া উচিত। সুতরাং যখন মেমরির চাপ থাকে তখন প্রথম জিনিসটি জেন ​​0 সংগ্রহ করে।

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

এর অর্থ হ'ল আপনি যদি এমন কিছু করেন:

~MyClass() { }

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

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


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

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


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

@ কোরিফয় "আপনার অবজেক্ট, তা যাই থাকুক না কেন, প্রজন্ম 2 তে বাঁচবে" এর জন্য কি কোনও দলিল আছে?
আশিস নেগি

33

ইতিমধ্যে এখানে প্রচুর ভাল আলোচনা হয়েছে, এবং আমি পার্টিতে কিছুটা দেরি করেছি, তবে আমি নিজে কয়েকটি পয়েন্ট যুক্ত করতে চেয়েছিলাম।

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

class SomeObject : IDisposable {
 IntPtr _SomeNativeHandle;
 FileStream _SomeFileStream;

 // Something useful here

 ~ SomeObject() {
  Dispose(false);
 }

 public void Dispose() {
  Dispose(true);
 }

 protected virtual void Dispose(bool disposing) {
  if(disposing) {
   GC.SuppressFinalize(this);
   //Because the object was explicitly disposed, there will be no need to 
   //run the finalizer.  Suppressing it reduces pressure on the GC

   //The managed reference to an IDisposable is disposed only if the 
   _SomeFileStream.Dispose();
  }

  //Regardless, clean up the native handle ourselves.  Because it is simple a member
  // of the current instance, the GC can't have done anything to it, 
  // and this is the onlyplace to safely clean up

  if(IntPtr.Zero != _SomeNativeHandle) {
   NativeMethods.CloseHandle(_SomeNativeHandle);
   _SomeNativeHandle = IntPtr.Zero;
  }
 }
}

এটি সাধারণ সংস্করণ, তবে এমন অনেকগুলি সূক্ষ্মতা রয়েছে যা আপনাকে এই প্যাটার্নে তুলে ধরতে পারে।

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

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

কেবল একটি SafeHandle সংজ্ঞায়িত করা এটিকে তুচ্ছ করে তোলে:


private class SomeSafeHandle
 : SafeHandleZeroOrMinusOneIsInvalid {
 public SomeSafeHandle()
  : base(true)
  { }

 protected override bool ReleaseHandle()
 { return NativeMethods.CloseHandle(handle); }
}

আপনাকে এতে থাকা ধরণটি সহজ করার অনুমতি দেয়:


class SomeObject : IDisposable {
 SomeSafeHandle _SomeSafeHandle;
 FileStream _SomeFileStream;
 // Something useful here
 public virtual void Dispose() {
  _SomeSafeHandle.Dispose();
  _SomeFileStream.Dispose();
 }
}

1
SafeHandleZeroOrMinusOneIsIn अवैध ক্লাসটি কোথা থেকে এসেছে? এটি নেট নেট টাইমে অন্তর্নির্মিত?
ওরিওন এডওয়ার্ডস

+1 এর জন্য // আমার মতে চূড়ান্তকরণের প্রয়োজন হতে পারে এমন ডিসপোজেবল তথ্যসূত্র এবং দেশীয় সম্পদ উভয়ই ধারণ করে এমনভাবে সম্পূর্ণরূপে এড়ানো ভাল // চূড়ান্ত।
সুপারক্যাট

1
@OrionEdwards হ্যাঁ দেখতে msdn.microsoft.com/en-us/library/...
মার্টিন Capodici

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

6

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


সম্পাদনা: আমি গিয়েছিলাম এবং পরীক্ষা করেছি, কেবল তা নিশ্চিত করার জন্য:

class Program
{
    static void Main(string[] args)
    {
        Fred f = new Fred();
        f = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Console.WriteLine("Fred's gone, and he's not coming back...");
        Console.ReadLine();
    }
}

class Fred : IDisposable
{
    ~Fred()
    {
        Console.WriteLine("Being finalized");
    }

    void IDisposable.Dispose()
    {
        Console.WriteLine("Being Disposed");
    }
}

নিষ্পত্তি করার সময় আপনার কাছে অব্যবহারযোগ্য অবজেক্টগুলি সম্পর্কে অনুমান করা বিপজ্জনক এবং কৌতুকপূর্ণ হতে পারে, বিশেষত চূড়ান্তকরণের সময়।
স্কট ডরম্যান

3

আপনি যেভাবে বর্ণনা করেছেন তেমন নয়, তবে জিসি আপনার কাছে ফিনালাইজারকে কল করবে ।

যাহোক. পরবর্তী আবর্জনা সংগ্রহের পরিবর্তে, বস্তুটি চূড়ান্তকরণের ক্যোতে যাবে, সমস্ত কিছু সংগ্রহ হয়ে যায়, তারপরে একে চূড়ান্তকরণকারী বলা হয়। তার পরের পরবর্তী সংগ্রহটি এটি মুক্ত করা হবে।

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


1

না, এটি বলা হয় না।

তবে এটি আপনার অবজেক্টগুলি নিষ্পত্তি করতে ভুলে যাওয়া সহজ করে তোলে। শুধু usingকীওয়ার্ডটি ব্যবহার করুন ।

আমি এর জন্য নিম্নলিখিত পরীক্ষাটি করেছি:

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo();
        foo = null;
        Console.WriteLine("foo is null");
        GC.Collect();
        Console.WriteLine("GC Called");
        Console.ReadLine();
    }
}

class Foo : IDisposable
{
    public void Dispose()
    {

        Console.WriteLine("Disposed!");
    }

1
এটি কীভাবে আপনি <code> </code> কীওয়ার্ড ব্যবহার না করে এটি কীওয়ার্ড না বলার একটি উদাহরণ ছিল ... এবং এই স্নিপেটটির 9 বছরের শুভ জন্মদিন!
পেনিয়াস্কিটো

1

জিসি ডিসপোজ কল করবেন না । এটি আপনার ফাইনালাইজারকে কল করতে পারে , তবে এমনকি এটি সমস্ত পরিস্থিতিতে গ্যারান্টিযুক্ত নয়।

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


0

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


0

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

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

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

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