স্টেটমেন্ট ব্যবহার শেষ হওয়ার আগে যদি আমি ফিরে আসি তবে কী হবে? নিষ্পত্তি বলা হবে?


115

আমি নিম্নলিখিত কোড আছে

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

dispose()পদ্ধতি শেষে বলা হয় usingবিবৃতিতে ধনুর্বন্ধনী }ঠিক আছে? আমি যেহেতু বিবৃতিটি returnশেষ হওয়ার আগে using, MemoryStreamবস্তুটি কি সঠিকভাবে নিষ্পত্তি করা হবে? এখানে কি হয়?


4
@ জোনএইচ: সঠিক সদৃশটি সন্ধান করুন, তারপরে দয়া করে দয়া করে বন্ধ করতে ভোট দিন।
নলডোরিন

@ নলডোরিন: আমি এটির জন্য একটি সন্ধান করতে গিয়েছিলাম, কারণ আমি বুঝতে পেরেছিলাম এটি অবশ্যই জিজ্ঞাসা করা হয়েছিল, তবে আমি এটির সন্ধান করতে পারিনি। আমার ধারণা এখনও সেখানে সহজ প্রশ্ন রয়েছে। :)
র্যান্ডল্ফো

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

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

আআপ ... আমি তা ফিরিয়ে নিই। আমি খুব উত্সর্গীকৃত অনুসন্ধানের পরে সবেমাত্র একটি কাছাকাছি সদৃশ খুঁজে পেয়েছি: stackoverflow.com/questions/2641692/… এখন, প্রশ্নটি সম্পূর্ণ আলাদাভাবে জিজ্ঞাসা করা হয়েছে, তবে চূড়ান্ত প্রশ্নটি বেশ প্রায় একই। আমি মনে করি আমরা সর্বোপরি এটিকে একটি ডুপ হিসাবে বিবেচনা করতে পারি।
র‌্যান্ডল্ফো

উত্তর:


167

হ্যাঁ, Disposeডাকা হবে। এটি শীঘ্রই ফাঁসি পাতার হিসাবে পরিধি যেমন বলা হচ্ছে usingব্লক, মানে কি এটা ব্লক ছেড়ে নেমে আসে নির্বিশেষে, ব্লক, একটি কার্যকর শেষ হতে returnবিবৃতি, অথবা একটি ব্যতিক্রম।

@ নলডোরিন সঠিকভাবে উল্লেখ করেছেন যে কোডে একটি usingব্লক ব্যবহার করে try/ এ ব্লকটিতে ডাকা হওয়ার finallyসাথে সংকলিত হয় । উদাহরণস্বরূপ নিম্নলিখিত কোড:Disposefinally

using(MemoryStream ms = new MemoryStream())
{
     //code
     return 0;
}

কার্যকরভাবে হয়ে:

MemoryStream ms = new MemoryStream();
try
{
    // code
    return 0;
}
finally
{
    ms.Dispose();
}

সুতরাং, যেহেতু ব্লকটি finallyকার্যকর কার্যকর হওয়ার পরে tryনির্বাহের পথ নির্বিশেষে নির্বাহের Disposeকাজটি নির্ধারণের গ্যারান্টিযুক্ত , যাই হোক না কেন ডেকে আনা গ্যারান্টিযুক্ত।

আরও তথ্যের জন্য, এই এমএসডিএন নিবন্ধটি দেখুন

সংযোজন: যুক্ত করার জন্য
কেবল একটি সামান্য সতর্কতা: কারণ Disposeএটির গ্যারান্টিযুক্ত, এটি Disposeবাস্তবায়নের সময় কখনই কোনও ব্যতিক্রম ছুঁড়ে না তা নিশ্চিত করা প্রায় সর্বদা একটি ভাল ধারণা IDisposable। দুর্ভাগ্যবশত, কোর লাইব্রেরিতে কিছু শ্রেণীর যে কি করতে কিছু বিশেষ পরিস্থিতির মধ্যে নিক্ষেপ যখন Disposeআমি তোমাদের দিকে তাকিয়ে আছি, WCF পরিষেবা রেফারেন্স / ক্লায়েন্ট প্রক্সি - বলা হয়! - এবং এটি যখন ঘটে তখন মূল ব্যতিক্রমটিকে কল করা খুব শক্ত হতে পারে যদি Disposeকোনও ব্যতিক্রম স্ট্যাক আনইন্ডাইন্ডের সময় ডাকা হত, যেহেতু মূল ব্যতিক্রমটি Disposeকল দ্বারা উত্পন্ন নতুন ব্যতিক্রমের পক্ষে গিলে যায় । এটি হতাশাজনক হতাশ হতে পারে। নাকি হতাশাজনকভাবে ক্ষিপ্ত? দুই এর মধ্যে এক. হয়তো উভয়.


4
আমি মনে করি আপনি এটি কার্যকরভাবে অবশেষে একটি কল সহ একটি চেষ্টা-অবরুদ্ধ ব্লকে সংকলিত পাবেন Dispose, সুতরাং এটি কার্যকরভাবে কার্যকরভাবে কার্যকর করছে finally, আপনি বর্ণনা হিসাবে।
নলডোরিন

@ নলডোরিন: ঠিক যদিও আমি মনে করি আমি এটি সম্পর্কে স্পষ্ট হতে পারে। আসন্ন সম্পাদনা করুন ....
র্যান্ডলফো

1
এছাড়াও মনে রাখবেন যে এমন কিছু পরিস্থিতি রয়েছে যা অবশেষে ব্লকটি কার্যকর করার গ্যারান্টিযুক্ত নয় যেমন এনভায়রনমেন্ট.ফয়েলফাস্ট ব্যবহার করা এবং যদি স্ট্যাকওভারফ্লোঅ্যাক্সেশন ঘটে থাকে।
ক্রিস্টোফার ম্যাকআটাকনি

@ সিএমসিএটাকনি: এটিও একটি ভাল বিষয়। এছাড়াও, আইআইআরসি, আউট অফ মেমরি এক্সসেপশন; মূলত যদি আপনি ব্যতিক্রমটি ধরতে না পারেন কারণ এটি একটি কার্যকর কার্যকর ব্যর্থতা, নিষ্পত্তি বলা হবে না। অবশ্যই, এরকম ক্ষেত্রে প্রোগ্রামটি ক্রমযুক্ত হওয়ার সাথে সাথে এটির জন্য বরাদ্দকৃত কোনও স্মৃতিও গ্যারান্টিযুক্ত, সুতরাং 99.9% ক্ষেত্রে এটি একটি নন-ইস্যু হয়, যদি না আপনি নিজের নিষ্পত্তি পদ্ধতিতে কোনও ফাইলকে লেখার মতো জঘন্য স্টাফ করছেন । বিপর্যয়মূলক প্রোগ্রাম ক্রাশ বাদে, এটি।
র্যান্ডল্ফো

আপনার কখনই ডাব্লুসিএফ-এর সাথে 'ব্যবহার ()' বিবৃতি ব্যবহার করা উচিত নয় - আরও তথ্যের জন্য এই নিবন্ধটি দেখুন। আমি ডাব্লুসিএফ প্রক্সিগুলির জন্য একটি স্নিপেট ব্যবহার করি: 'ডাব্লুসিএফপ্রক্সি ভেরিয়েবল নাম = নাল; চেষ্টা করুন {ভেরিয়েবলনেম = নতুন ডাব্লুসিএফপ্রক্সি (); // এখানে TODO কোড ভেরিয়েবলনেম.প্রক্সি.ক্লোজ (); variableName.Dispose (); } ধরা (ব্যতিক্রম) {যদি (ভেরিয়েবল নাম! = নাল && ভেরিয়েবলনেম.প্রক্সি! = নাল) {ভ্যারিয়েবলনেম.প্রক্সি.অবর্ট (); } নিক্ষেপ; } '
ডেভ ব্ল্যাক

18

usingবিবৃতি হুবহু try ... finallyব্লকের মতো আচরণ করে , তাই কোনও কোড থেকে বেরিয়ে যাওয়ার পথে সর্বদা কার্যকর করা হবে। তবে আমি বিশ্বাস করি যে এগুলি খুব কম এবং বিরল পরিস্থিতিতে finallyসাফল্য রয়েছে যেখানে ব্লকগুলি বলা হয় না। একটি উদাহরণ যা আমি মনে করতে পারি তা হ'ল যদি পটভূমি থ্রেড সক্রিয় থাকাকালীন অগ্রভাগের থ্রেডটি প্রস্থান করে: জিসি ব্যতীত সমস্ত থ্রেড থেমে রয়েছে, যার অর্থ finallyব্লকগুলি চালিত হয় না।

সুস্পষ্ট সম্পাদনা: তারা যুক্তি বাদে একইরকম আচরণ করে যা তাদেরকে আইডিজিপোজেবল অবজেক্টগুলি হ্যান্ডেল করতে দেয় '

বোনাস সামগ্রী: তারা স্ট্যাক করা যেতে পারে (যেখানে ধরণের পার্থক্য রয়েছে):

using (SqlConnection conn = new SqlConnection("string"))
using (SqlCommand comm = new SqlCommand("", conn))
{

}

এবং কমা-বিস্মৃত (যেখানে প্রকারগুলি একই):

using (SqlCommand comm = new SqlCommand("", conn), 
       SqlCommand comm2 = new SqlCommand("", conn))
{

}

4

আপনার মেমোরিস্ট্রিম অবজেক্টটি সঠিকভাবে নিষ্পত্তি হবে, এটি নিয়ে কোনও চিন্তা করার দরকার নেই।



0

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

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