আপনি কীভাবে আপনার সমস্ত ক্লাসে ছড়িয়ে পড়া থেকে আটকে যেতে পারেন?


138

এই সাধারণ ক্লাস দিয়ে শুরু করুন ...

ধরা যাক আমার কাছে ক্লাসগুলির একটি সহজ সেট রয়েছে:

class Bus
{
    Driver busDriver = new Driver();
}

class Driver
{
    Shoe[] shoes = { new Shoe(), new Shoe() };
}

class Shoe
{
    Shoelace lace = new Shoelace();
}

class Shoelace
{
    bool tied = false;
}

Busএর একটি আছে Driver, Driverদুটিতে রয়েছে Shoe, প্রত্যেকের Shoeরয়েছে একটি Shoelace। সব খুব নিরীহ।

জুতার একটি আইডিজিপোজযোগ্য বস্তু যুক্ত করুন

পরে আমি স্থির করি যে এর উপর কিছু অপারেশন Shoelaceবহু-থ্রেডযুক্ত হতে পারে, তাই EventWaitHandleথ্রেডগুলির সাথে যোগাযোগের জন্য আমি একটি যুক্ত করি । সুতরাং Shoelaceএখন এই মত দেখাচ্ছে:

class Shoelace
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;
    // ... other stuff ..
}

জুতার উপর আইডিজিপোজযোগ্য প্রয়োগ করুন

তবে এখন মাইক্রোসফ্টের এফএক্সকপ অভিযোগ করবে: "'জুতো'-তে আইডিজিপোজযোগ্য প্রয়োগ করুন কারণ এটি নিম্নলিখিত আইডিজিপোজযোগ্য প্রকারের সদস্যদের তৈরি করে:' ইভেন্টওয়েটহ্যান্ডেল '।

ঠিক আছে, আমি বাস্তবায়ন IDisposableউপর Shoelaceএবং আমার ঝরঝরে সামান্য বর্গ এই ভয়ঙ্কর জগাখিচুড়ি হয়ে:

class Shoelace : IDisposable
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;
    private bool disposed = false;

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

    ~Shoelace()
    {
        Dispose(false);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                if (waitHandle != null)
                {
                    waitHandle.Close();
                    waitHandle = null;
                }
            }
            // No unmanaged resources to release otherwise they'd go here.
        }
        disposed = true;
    }
}

অথবা (কমেন্টাররা উল্লেখ করেছেন) যেহেতু Shoelaceনিজের কোনও ব্যবস্থাপনিত সংস্থান নেই, তাই আমি Dispose(bool)এবং ডেস্ট্রাক্টরের প্রয়োজন ছাড়াই সহজতর নিষ্পত্তি বাস্তবায়নটি ব্যবহার করতে পারি :

class Shoelace : IDisposable
{
    private AutoResetEvent waitHandle = new AutoResetEvent(false);
    bool tied = false;

    public void Dispose()
    {
        if (waitHandle != null)
        {
            waitHandle.Close();
            waitHandle = null;
        }
        GC.SuppressFinalize(this);
    }
}

আইডিস্পোজেবল ছড়িয়ে পড়ার সাথে সাথে হররে দেখুন

ঠিক যে স্থির। তবে এখন এফএক্সকপ অভিযোগ করবে যে এটি Shoeতৈরি করে Shoelace, তাই Shoeঅবশ্যই হবে IDisposable

এবং Driverতৈরি Shoeতাই Driverহতে হবে IDisposable। এবং Busক্রিয়েটস Driverতাই Busঅবশ্যই হবে IDisposableএবং তাই।

হঠাৎ করে আমার ছোট্ট পরিবর্তনটি Shoelaceআমাকে প্রচুর পরিশ্রমের কারণ করছে এবং আমার বস ভাবছেন যে কেন আমাকে এই Busপরিবর্তনটি করার জন্য চেকআউট করতে হবে Shoelace

প্রশ্নটি

আপনি কীভাবে এই IDisposableপ্রসারকে আটকাবেন, তবে তবুও নিশ্চিত করুন যে আপনার নিয়ন্ত্রণহীন অবজেক্টগুলি সঠিকভাবে নিষ্পত্তি করা হয়েছে?


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

ঠিক আছে ড্যান, আমি জুতার উপর আইডিজিপোজেবল প্রয়োগের দুটি পদ্ধতি দেখানোর জন্য প্রশ্নটি আপডেট করেছি।
গ্রাহামস

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

@ ড্যান: অবজেক্টটি নিজেই বাতিল হয়ে গেছে না তা নিশ্চিত করার জন্য নাল চেকটি এখনও দরকার, সেক্ষেত্রে ওয়েটহ্যান্ডল.ডিসপজ () -তে কলটি একটি নালরফেরান এক্সেকশন নিক্ষেপ করবে।
স্কট ডরম্যান

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

উত্তর:


36

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

  • যেখানে সম্ভব আইডিসপোজেবল ক্লাস ব্যবহার করা এড়ানো, একক স্থানে লক করা বা ইভেন্টের জন্য অপেক্ষা করা, ব্যয়বহুল সংস্থানগুলি এক জায়গায় রাখুন ইত্যাদি
  • আপনার যখন প্রয়োজন হয় তখনই এগুলি তৈরি করুন এবং ঠিক ( usingপ্যাটার্ন) পরে নিষ্পত্তি করুন

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


4
আপনি যে পরামর্শটি এটিকে উপেক্ষা করতে পারেন কারণ বাস্তবায়ন আজ কিছুই করেনা তা খারাপ, কারণ ভবিষ্যতের সংস্করণটি বাস্তবে ডিসপোজ-এ গুরুত্বপূর্ণ কিছু করতে পারে এবং এখন আপনার ফাঁস হ্রাস করা শক্ত হয়ে উঠছে।
অ্যান্ডি

1
"ব্যয়বহুল সংস্থান রাখুন", আইডিস্পোজেবলগুলি অগত্যা ব্যয়বহুল নয়, প্রকৃতপক্ষে এই উদাহরণটি যা এমনকি ওয়েট হ্যান্ডেল ব্যবহার করে আপনি যেমন পাবেন তেমনই "হালকা ওজন" is
মার্কমনল

20

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

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

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


2
সেখানে অ্যাসোসিয়েশন করা খুব অদ্ভুত লাগে। এই অটোসেটসেন্টটি শোলেস বাস্তবায়নের জন্য ব্যক্তিগত, তাই এটি প্রকাশ্যে প্রকাশ করা আমার মতে ভুল হবে।
গ্রাহামস

@ গ্রাহামস, আমি প্রকাশ্যে বলছি না। আমি বলছি, এটিকে কী এমন জায়গায় স্থানান্তরিত করা যেতে পারে যেখানে জুতো বাঁধা আছে? জুতার লেইসগুলি বেঁধে রাখা যদি এমন জটিল কাজ হয় তবে তাদের উচিত জুতার স্তর স্তর।
জেয়ার্ডপার

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

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

16

IDisposableছড়িয়ে পড়া রোধ করতে আপনার একক পদ্ধতির অভ্যন্তরে ডিসপোজেবল অবজেক্টের ব্যবহার সজ্জিত করার চেষ্টা করা উচিত। Shoelaceআলাদাভাবে ডিজাইনের চেষ্টা করুন :

class Shoelace { 
  bool tied = false; 

  public void Tie() {

    using (var waitHandle = new AutoResetEvent(false)) {

      // you can even pass the disposable to other methods
      OtherMethod(waitHandle);

      // or hold it in a field (but FxCop will complain that your class is not disposable),
      // as long as you take control of its lifecycle
      _waitHandle = waitHandle;
      OtherMethodThatUsesTheWaitHandleFromTheField();

    } 

  }
} 

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

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


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

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

2
দুঃখিত, আমি জানি আপনি প্রায় নিষ্পত্তিযোগ্য পাস করতে পারেন, কিন্তু আমি এখনও এটি কাজ দেখছি না। আমার উদাহরণে এটি AutoResetEventএকই বর্গের মধ্যে কাজ করে এমন বিভিন্ন থ্রেডের মধ্যে যোগাযোগ করার জন্য ব্যবহৃত হয়, সুতরাং এটির সদস্য পরিবর্তনশীল হতে হবে। আপনি এর ব্যবস্থাকে কোনও পদ্ধতির মধ্যে সীমাবদ্ধ করতে পারবেন না। (উদাহরণস্বরূপ কল্পনা করুন যে একটি থ্রেড কেবল অবরুদ্ধ হয়ে কিছু কাজের জন্য অপেক্ষা করছে waitHandle.WaitOne()The মূল থ্রেডটি তখন shoelace.Tie()পদ্ধতিটিকে কল করে , যা কেবল একটি করে waitHandle.Set()এবং সঙ্গে সঙ্গে ফিরে আসে)।
গ্রাহামস

3

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

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

তবে আপনি ডেস্ট্রাক্টর এবং জিসি.সপ্রেসফাইনালাইজ (এটি) বাদ দিতে পারেন; এবং সম্ভবত ভার্চুয়াল শূন্যতা নিষ্পত্তি (বুল নিষ্পত্তি) কিছুটা সাফ করুন।


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

আপনাকে কেবল তৈরির কাজই নয়, ওয়েটহ্যান্ডলটির 'দায়বদ্ধতা' চালানো দরকার। jaredPar এর উত্তর একটি ধারণা একটি আকর্ষণীয় শুরু আছে।
হেন্ক হলটারম্যান

এই ব্লগটি আইডিজিপোজেবল বাস্তবায়ন এবং বিশেষভাবে সম্বোধনগুলিতে কীভাবে একটি একক শ্রেণীর ব্লগে
পেনস্প্লিলারি.

3

আকর্ষণীয়ভাবে যদি Driverউপরে বর্ণিত হয়:

class Driver
{
    Shoe[] shoes = { new Shoe(), new Shoe() };
}

তারপরে যখন Shoeতৈরি করা হয় IDisposable, FxCop (v1.36) Driverএটিও হওয়া উচিত বলে অভিযোগ করে না IDisposable

তবে যদি এটি এর মতো সংজ্ঞায়িত হয়:

class Driver
{
    Shoe leftShoe = new Shoe();
    Shoe rightShoe = new Shoe();
}

তাহলে এটি অভিযোগ করবে।

আমি সন্দেহ করি যে এটি সমাধানের পরিবর্তে এটি FxCop এর সীমাবদ্ধতা, কারণ প্রথম সংস্করণে Shoeউদাহরণগুলি এখনও তৈরি করেছে Driverএবং এখনও কোনওভাবে নিষ্পত্তি করা দরকার।


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

1
@ সুপের্যাট: ধন্যবাদ কেন আপনি এটি বিপজ্জনক ব্যাখ্যা করতে পারেন ? আমি অনুমান করছি যে যদি কোনও ব্যতিক্রম কোনও Shoeকনস্ট্রাক্টরের মধ্যে ছুঁড়ে দেওয়া হয় তবে shoesকি একটি কঠিন অবস্থায় ফেলে রাখা হবে?
গ্রাহামস

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

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

3

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

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

একটি বিকল্প নকশা হতে পারে:

class Bus
{
   IDriver busDriver = null;
   public void SetDriver(IDriver d) { busDriver = d; }
}

class Driver : IDriver
{
   IShoePair shoes = null;
   public void PutShoesOn(IShoePair p) { shoes = p; }
}

class ShoePairWithDisposableLaces : IShoePair, IDisposable
{
   Shoelace lace = new Shoelace();
}

class Shoelace : IDisposable
{
   ...
}

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


2
এটি যদিও আসল সমস্যাটি আসলেই সমাধান করে না। এটি এফএক্সকপকে চুপ করে থাকতে পারে তবে কিছুতে এখনও জুতার নিষ্পত্তি করা উচিত।
অ্যান্ড্রুস

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

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

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

1
@ গ্রাহাম: হ্যাঁ, কোনও ধরণের একটি বিজ্ঞপ্তি দরকার হবে। রেফারেন্স গণনার উপর ভিত্তি করে একটি নিষ্পত্তি নীতি ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ। কিছু যোগ জটিলতা, কিন্তু আপনি সম্ভবত জানেন, :) "একটা বিনামূল্যে জুতা যেমন জিনিস" -এর
Joh

1

ইনভারসন অফ কন্ট্রোল কীভাবে ব্যবহার করবেন?

class Bus
{
    private Driver busDriver;

    public Bus(Driver busDriver)
    {
        this.busDriver = busDriver;
    }
}

class Driver
{
    private Shoe[] shoes;

    public Driver(Shoe[] shoes)
    {
        this.shoes = shoes;
    }
}

class Shoe
{
    private Shoelace lace;

    public Shoe(Shoelace lace)
    {
        this.lace = lace;
    }
}

class Shoelace
{
    bool tied;
    private AutoResetEvent waitHandle;

    public Shoelace(bool tied, AutoResetEvent waitHandle)
    {
        this.tied = tied;
        this.waitHandle = waitHandle;
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var leftShoeWaitHandle = new AutoResetEvent(false))
        using (var rightShoeWaitHandle = new AutoResetEvent(false))
        {
            var bus = new Bus(new Driver(new[] {new Shoe(new Shoelace(false, leftShoeWaitHandle)),new Shoe(new Shoelace(false, rightShoeWaitHandle))}));
        }
    }
}

এখন আপনি এটিকে কলারদের সমস্যা তৈরি করেছেন এবং শোলস যখন প্রয়োজন হবে তখন ওয়েট হ্যান্ডেলটি উপলভ্য হওয়ার উপর নির্ভর করতে পারে না।
অ্যান্ডি

@ এবং আপনি "জুতো যখন অপেক্ষা করা হ্যান্ডেল এটির প্রয়োজন হয় তখন তার উপর নির্ভর করতে পারে না" এর অর্থ কী? এটি কনস্ট্রাক্টরের কাছে পৌঁছেছে।
দারাগ

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

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

ওপিস উদাহরণটিতে ব্যক্তিগত সদস্য হিসাবে ওয়েটহান্ডেল রয়েছে তা দেওয়া, নিরাপদ অনুমানটি হ'ল বস্তুটি এতে একচেটিয়া অ্যাক্সেসের প্রত্যাশা করে। হ্যান্ডেলটি দৃশ্যমানের বাইরে দৃশ্যমান করা লঙ্ঘন করে। সাধারণত একটি আইওসি এই জাতীয় জিনিসগুলির জন্য ভাল হতে পারে তবে থ্রেডিংয়ের ক্ষেত্রে আসে না।
অ্যান্ডি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.