স্কেলডাটাআডারকে ম্যানুয়ালি বন্ধ এবং নিষ্পত্তি করা কি প্রয়োজনীয়?


90

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

এটি কি পারফরম্যান্সে মন্দার কারণ হতে পারে?

উত্তর:


125

পাঠকদের এভাবে ব্যবহার না করার চেষ্টা করুন:

SqlConnection connection = new SqlConnection("connection string");
SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection);
SqlDataReader reader = cmd.ExecuteReader();
connection.Open();
if (reader != null)
{
      while (reader.Read())
      {
              //do something
      }
}
reader.Close(); // <- too easy to forget
reader.Dispose(); // <- too easy to forget
connection.Close(); // <- too easy to forget

পরিবর্তে, তাদের বিবৃতি ব্যবহার করে মোড়ানো:

using(SqlConnection connection = new SqlConnection("connection string"))
{

    connection.Open();

    using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
    {
        using (SqlDataReader reader = cmd.ExecuteReader())
        {
            if (reader != null)
            {
                while (reader.Read())
                {
                    //do something
                }
            }
        } // reader closed and disposed up here

    } // command disposed here

} //connection closed and disposed here

ব্যবহারের বিবৃতিটি অবজেক্টের সঠিক নিষ্পত্তি এবং সংস্থানগুলি মুক্ত করার বিষয়টি নিশ্চিত করবে।

যদি আপনি ভুলে যান তবে আপনি পরিষ্কার-পরিচ্ছন্নতা আবর্জনা সংগ্রহকারীকে ছেড়ে দিচ্ছেন, এতে কিছুটা সময় লাগতে পারে।


24
আপনার উভয় নমুনায়। ক্লোজ () বিবৃতি দরকার নেই: এটি .Dispose () কল দ্বারা পরিচালিত হয়।
জোয়েল কোহোর্ন

7
সম্ভবত এটি যাচাই করতে চান .হসরগুলি বরং নালার।
জোনএইচ

4
@ অ্যান্ড্রু যদি এক্সিকিউটরেডার একটি ব্যতিক্রম ছুঁড়ে ফেলে তবে কীভাবে তা বাতিল হয়ে যায়?
csauve

7
@ জোহহ: উদাহরণটিতে (পাঠক। পড়ুন ()) একইভাবে কাজ করে asহসরোস, এবং আপনার প্রয়োজন। পাঠককে প্রথম সারিতে এগিয়ে যাওয়ার জন্য যাইহোক পড়ুন।
csauve

4
@ স্যাকউভ আপনি ঠিক বলেছেন, আমার ধারণা এটি অবশ্যই বাতিল হয় নি। আমি নিশ্চিত নই যে আমি কেন স্ক্যালডিটাআরডিডার ভেরিয়েবলের মান খুঁজছিলাম।
অ্যান্ড্রু

54

নোট করুন যে স্কেলকম্যান্ড ব্যবহার করে ইনস্ট্যান্টিয়েটেড স্কেলডাটাআরডারকে ডিসপোজ করা হয়েছে x এক্সিকিউটআরডার () অন্তর্নিহিত সংযোগটি বন্ধ / নিষ্পত্তি করবে না

দুটি সাধারণ নিদর্শন রয়েছে। প্রথমটিতে, পাঠক সংযোগের ক্ষেত্রের মধ্যে খোলা এবং বন্ধ করা হয়:

using(SqlConnection connection = ...)
{
    connection.Open();
    ...
    using(SqlCommand command = ...)
    {
        using(SqlDataReader reader = command.ExecuteReader())
        {
            ... do your stuff ...
        } // reader is closed/disposed here
    } // command is closed/disposed here
} // connection is closed/disposed here

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

public SqlDataReader ExecuteReader(string commandText)
{
    SqlConnection connection = new SqlConnection(...);
    try
    {
        connection.Open();
        using(SqlCommand command = new SqlCommand(commandText, connection))
        {
            return command.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }
    catch
    {
        // Close connection before rethrowing
        connection.Close();
        throw;
    }
}

এবং কলিং কোডটি কেবল পাঠককে এইভাবে নিষ্পত্তি করতে হবে:

using(SqlDataReader reader = ExecuteReader(...))
{
    ... do your stuff ...
} // reader and connection are closed here.

দ্বিতীয় কোড স্নিপেটে যেখানে পদ্ধতিটি স্কেলডিটাআরেডার প্রদান করে কমান্ডটি নিষ্পত্তি হয় না। এটি কি ঠিক আছে এবং কমান্ডটি নিষ্পত্তি করা (এটি একটি ব্যবহারের ব্লকে আবদ্ধ) এবং তারপরে পাঠককে ফিরিয়ে দেওয়া ঠিক আছে?
সর্বদা আলোকপাত করা

@ যেহেতু আমার ঠিক সেই দৃশ্যের বিষয়টি পরিষ্কার করে দেওয়া ...... আপনি যখন কলটিতে সিক্ল্যাডাটা রিডারটি ফিরিয়ে দিচ্ছেন তখন কি আপনি স্কেলকম্যান্ড বন্ধ / নিষ্পত্তি করতে পারবেন?
ganders

4
এইটা খারাপ. আপনি যদি সত্যিই এটি ব্যবহার করতে না পারছেন usingতবে finally {}ধরা পড়ার পরে ব্লকটিতে কল নিষ্পত্তি করুন । এটি যেভাবে লেখা হয়েছে, সফল আদেশগুলি কখনই বন্ধ বা নিষ্পত্তি হবে না।
স্ম্যাড্রাজার

4
@ এসএমড্রেজার, আপনি উত্তরটি নিকটে পড়লে তিনি এমন একটি পদ্ধতির কথা বলছেন যা পাঠককে ফেরত দেয়। আপনি যদি .ExecuteReader (কমান্ডবিহেভিয়ার.ক্লোজো কানেকশন) ব্যবহার করেন; তারপরে READER কে নিষ্পত্তি করার মাধ্যমে সংযোগটি বন্ধ হয়ে যাবে। সুতরাং কলিং পদ্ধতিটি কেবলমাত্র একটি ব্যবহারের বিবৃতিতে ফলাফল পাঠককে মোড়ানো প্রয়োজন। (var rdr = SqlHelper.GetReader ()) {// ... using ব্যবহার করে আপনি যদি শেষ অবধি এটি বন্ধ করে রাখেন তবে সংযোগটি বন্ধ থাকায় আপনার পাঠক পড়তে ব্যর্থ হবেন।
সিনাইস্টেথিক

@ গেন্ডার্স - এই পুরাতন পোস্টে ফিরে আসছে: হ্যাঁ আপনি এবং সম্ভবত স্কেলকম্যান্ড নিষ্পত্তি করতে পারেন - এটি করার উদাহরণটি আপডেট করেছেন।
জো

11

নিরাপদ থাকতে, প্রতিটি স্কেলডাটাআরডার বস্তুকে একটি ব্যবহারের বিবৃতিতে মোড়ানো করুন ।


যথেষ্ট ফর্সা। যাইহোক, যদি কোনও ব্যবহারের বিবৃতি না পাওয়া যায় তবে এটি কি কার্য সম্পাদনে কোনও পার্থক্য করে?
জন Ownbey

একটি ব্যবহারের বিবৃতিটি শেষের অংশে ক্লোজ / ডিসপোজ পদ্ধতিতে একটি চেষ্টা..ফিনালি ... ব্লক করে ডেটা রিডার কোডটি মোড়ানো সমান। মূলত, এটি কেবল "গ্যারান্টি" দেয় যে অবজেক্টটি সঠিকভাবে নিষ্পত্তি হবে।
টড

4
এটি আমার সরবরাহিত লিঙ্কটি থেকে সরাসরি: "ব্যবহারের বিবৃতিটি নিশ্চিত করে যে আপনি যখন অবজেক্টে পদ্ধতিগুলি কল করার সময় কোনও ব্যতিক্রম ঘটে তখনও ডিসপোজ বলা হয়" "
কন

6
অবিরত ... "আপনি অবজেক্টটিকে ট্রাই ব্লকের ভিতরে রেখে এবং পরে ডিসপোজকে শেষ অবধি কল করে একই ফলাফল অর্জন করতে পারেন; বাস্তবে, সংকলক দ্বারা এভাবেই ব্যবহারের বিবৃতিটি অনুবাদ করা হয়।"
কন

5

কেবলমাত্র আপনার এসকিউএলডাটা রিডারকে "ব্যবহার করে" স্টেটমেন্ট দিয়ে মুড়িয়ে দিন। এটি আপনার বেশিরভাগ সমস্যার যত্ন নেওয়া উচিত।

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