এর মধ্যে কোনও ব্যতিক্রম ঘটলে কোনও লক করা অবজেক্ট কী লক থাকে?


87

এসি # থ্রেডিং অ্যাপ্লিকেশনটিতে, আমি যদি কোনও বস্তুকে লক করে রাখি, আসুন একটি সারি বলি, এবং যদি কোনও ব্যতিক্রম ঘটে, তবে কী অবজেক্টটি লক থাকবে? এখানে সিউডো কোডটি রয়েছে:

int ii;
lock(MyQueue)
{
   MyClass LclClass = (MyClass)MyQueue.Dequeue();
   try
   {
      ii = int.parse(LclClass.SomeString);
   }
   catch
   {
     MessageBox.Show("Error parsing string");
   }
}

আমি এটি বুঝতে পেরেছি, ক্যাচের পরে কোডটি কার্যকর হয় না - তবে আমি ভাবছিলাম যে লকটি মুক্তি দেওয়া হবে কিনা।


4
চূড়ান্ত চিন্তার হিসাবে (আপডেটগুলি দেখুন) - আপনার সম্ভবত সম্ভবত ডিকুর সময়কালের জন্য লকটি রাখা উচিত ... লকটির বাইরে প্রসেসিং করা উচিত ।
মার্ক Gravell

4
ক্যাচের পরে কোডটি কার্যকর করে কারণ ব্যতিক্রমটি পরিচালনা করা হয়
সিজেকে

ধন্যবাদ আমি অবশ্যই এটি মিস করেছি, আমি কি এই প্রশ্নটি মুছতে পারি?
Vort3x

4
দেখে মনে হচ্ছে এই প্রশ্নের জন্য নমুনা কোডটি ভাল নয় তবে প্রশ্নটি বেশ কার্যকর।
সালভাদোরগোমেজ

সি # ডিজাইনার দ্বারা - লক এবং ব্যতিক্রম
জীবন

উত্তর:


91

প্রথম; আপনি ট্রাইপার্স বিবেচনা করেছেন?

in li;
if(int.TryParse(LclClass.SomeString, out li)) {
    // li is now assigned
} else {
    // input string is dodgy
}

লকটি 2 কারণে প্রকাশ করা হবে; প্রথমত, lockমূলত:

Monitor.Enter(lockObj);
try {
  // ...
} finally {
    Monitor.Exit(lockObj);
}

দ্বিতীয়; আপনি ধরেন এবং অভ্যন্তরীণ ব্যতিক্রমটিকে পুনরায় নিক্ষেপ করবেন না, তাই lockবাস্তবে কখনই ব্যতিক্রম দেখা যায় না। অবশ্যই, আপনি একটি বার্তাবক্সের সময়কালের জন্য লকটি ধরে আছেন, যা কোনও সমস্যা হতে পারে।

সুতরাং এটি সবচেয়ে মারাত্মক বিপর্যয় অপরিবর্তনযোগ্য ব্যতিক্রম বাদে সকলের মধ্যে প্রকাশিত হবে।


15
আমি ট্রাইপার্স সম্পর্কে সচেতন, তবে এটি আমার প্রশ্নের সাথে সত্যই প্রাসঙ্গিক নয়। প্রশ্নটি ব্যাখ্যা করার জন্য এটি সহজ কোড ছিল - পার্স সম্পর্কিত কোনও সত্য উদ্বেগ নয়। দয়া করে এমন কোনও কোডের সাথে পার্স প্রতিস্থাপন করুন যা ক্যাচটিকে বাধ্য করবে এবং আপনাকে আরামদায়ক করবে।
খাজাজি

13
কীভাবে নতুন ব্যতিক্রম ছোঁড়াবেন ("উদাহরণস্বরূপ উদ্দেশ্যে"); ;-p
মার্ক Gravell


4
"মারাত্মক বিপর্যয় অপরিবর্তনযোগ্য ব্যতিক্রম" স্রোত অতিক্রম করার মতো like
ফিল কুপার

99

আমি নোট করেছি যে এই পুরানো প্রশ্নের তাদের উত্তরে কেউ উল্লেখ করেনি যে একটি ব্যতিক্রমকে তালাবদ্ধ করে দেওয়া একটি অবিশ্বাস্যরকম বিপজ্জনক কাজ। হ্যাঁ, সি # তে লক স্টেটমেন্টগুলিতে "অবশেষে" শব্দার্থবিজ্ঞান রয়েছে; যখন নিয়ন্ত্রণটি স্বাভাবিক বা অস্বাভাবিকভাবে লকটি থেকে বের হয়, তখন লকটি প্রকাশ হয়। আপনি সকলেই এ জাতীয় কথা বলছেন এটি ভাল জিনিস তবে এটি খারাপ জিনিস! যদি আপনার কাছে কোনও লকড অঞ্চল রয়েছে যা অবিবাহিত ব্যতিক্রম ছুঁড়েছে তবে সঠিক কাজটি হ'ল অসুস্থ প্রক্রিয়াটি আরও বেশি ব্যবহারকারীর ডেটা নষ্ট করার আগেই তা বন্ধ করে দেওয়া , লকটি মুক্ত না করে চালিয়ে যাওয়া

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

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

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

আপনি এটি কীভাবে টুকরো টুকরো টুকরো টুকরো টুকরো না করে একটি লকের অভ্যন্তরে ব্যতিক্রম হ'ল খারাপ খবর । জিজ্ঞাসা করার জন্য সঠিক প্রশ্নটি নয় "ব্যতিক্রম ঘটলে আমার লকটি কি পরিষ্কার হয়ে যাবে?" জিজ্ঞাসা করার সঠিক প্রশ্নটি হ'ল "আমি কীভাবে তা নিশ্চিত করব যে কোনও তালার অভ্যন্তরে কখনই ব্যতিক্রম থাকবে না? এবং যদি সেখানে থাকে তবে আমি কীভাবে আমার প্রোগ্রামটি গঠন করব যাতে পরিবর্তনগুলি পূর্ববর্তী ভাল অবস্থানে ফিরে যায়?"


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

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

4
@ জিরাসিমোসআর: সত্যই। জোর দেওয়ার জন্য দুটি পয়েন্ট। প্রথমে, ব্যতিক্রম সৌম্যরূপে নির্ধারিত না হওয়া অবধি বিপর্যয়ী বলে ধরে নেওয়া উচিত। দ্বিতীয়ত, আপনি যদি কোনও লক অঞ্চল থেকে ছিটকে সৌম্যর ব্যতিক্রম পেয়ে থাকেন তবে লক অঞ্চলটি সম্ভবত খারাপভাবে ডিজাইন করা হয়েছে; এটি সম্ভবত লকের ভিতরে অনেক বেশি কাজ করছে।
এরিক লিপার্ট

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

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

43

হ্যাঁ, এটি সঠিকভাবে মুক্তি পাবে; অবশেষে এর সাথে / lockহিসাবে হিসাবে কাজ করে, সুতরাং আপনি কীভাবে এটি প্রস্থান করবেন তা প্রকাশিত হবে না। পার্শ্ব-নোট হিসাবে, সেরা এড়ানো হয়, কারণ এটি স্ট্যাক-ট্রেসকে ক্ষতিগ্রস্থ করে ; এটা ভাল এটা ধরা নয় এ সব ব্যবহার:, বা অন্যভাবে বদলে যা পুনরায় নিক্ষেপ করে।tryfinallyMonitor.Exit(myLock)catch(... e) {throw e;}ethrow;throw e;

আপনি যদি সত্যিই জানতে চান, সি # 4 /। নেট 4 এ একটি লক হ'ল:

{
    bool haveLock = false;
    try {
       Monitor.Enter(myLock, ref haveLock);
    } finally {
       if(haveLock) Monitor.Exit(myLock);
    }
} 

14

"একটি লক স্টেটমেন্টটি মনিটরে কল করে একটি সংকলিত হয় n

X86 এবং x64 উভয়ের জন্য জেআইটি কোড জেনারেশন নিশ্চিত করে যে কোনও মনিটরের মধ্যে একটি থ্রেড অ্যাওর্ট না ঘটতে পারে call

থেকে নেওয়া: এই সাইটটি


4
কমপক্ষে একটি ক্ষেত্রে এটি সত্য নয়: net এর আগে। নেট সংস্করণগুলিতে ডিবাগ মোডে থ্রেড গর্ভপাত The কারণটি হ'ল সি # সংকলকটি Monitor.Enterএবং এর মধ্যে একটি এনওপি সন্নিবেশ করায় tryযাতে "অবিলম্বে অনুসরণ করে" শর্তটি জেআইটি লঙ্ঘিত হয়।
কোডসইনচাউস

6

আপনার লকটি সঠিকভাবে প্রকাশিত হবে। এর lockমতো একটি কাজ:

try {
    Monitor.Enter(myLock);
    // ...
} finally {
    Monitor.Exit(myLock);
}

এবং finallyব্লকগুলি কার্যকর করার গ্যারান্টিযুক্ত, আপনি যেভাবে tryব্লকটি রেখে যান তা নির্বিশেষে ।


আসলে, কোন কোড "নিশ্চিত" হয় (আপনি উদাহরণস্বরূপ, পাওয়ার কেবল টান পারে) চালানো, এবং যে হয় না বেশ কি 4.0 মত একটি লক সৌন্দর্য - এখানে দেখতে
মার্ক Gravell

4
@ মার্কগ্রাভেল: আমি ঠিক এই দুটি পয়েন্ট সম্পর্কে দুটি পাদটীকা রাখার বিষয়ে ভেবেছিলাম। এবং তারপরে আমি অনুভব করেছি যে এটি খুব বেশি
গুরুত্ব

4
@ মার্কগ্রাভেল: আমি মনে করি সকলেই সর্বদা অনুমান করে যে কেউ 'প্লাগ টানুন' পরিস্থিতি সম্পর্কে কথা বলছে না, কারণ এটি কোনও প্রোগ্রামারের নিয়ন্ত্রণের বিষয় নয় :)
ভোর্ট

5

শুধু মার্কের দুর্দান্ত উত্তরে কিছুটা যুক্ত করা।

এর মতো পরিস্থিতিগুলি মূলশব্দটির অস্তিত্বের খুব কারণ lock। এটি বিকাশকারীদের নিশ্চিত করতে সহায়তা করে যে লকটি finallyব্লকটিতে প্রকাশিত হয়েছে ।

আপনাকে ব্যবহার বাধ্য থাকেন Monitor.Enter/ Exitএকটি টাইমআউটের সমর্থন করার জন্য যেমন, আপনি কি নিশ্চিতরূপে থেকে কল স্থাপন করতে হবে Monitor.Exitযে finallyব্লক একটি ব্যতিক্রম ক্ষেত্রে লক সঠিক মুক্তি নিশ্চিত করতে হবে।

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