هل SQLCommand.Dispose () مطلوب إذا تم التخلص من SQLConnection المرتبطة؟

StackOverflow https://stackoverflow.com/questions/1808036

سؤال

عادة ما أستخدم رمز مثل هذا:

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
{
   var command = connection.CreateCommand();
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}

سوف بلدي command التخلص تلقائيا؟ أو لا يجب أن ألفها using الكتلة؟ هل هو مطلوب للتخلص منه SqlCommand?

هل كانت مفيدة؟

المحلول

فقط افعل هذا:

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
using(var command = connection.CreateCommand())
{
   command.CommandText = "...";
   connection.Open();
   command.ExecuteNonQuery();
}

عدم الاتصال بالتخلص من الأمر لن يفعل أي شيء سيء للغاية. ومع ذلك ، فإن الاتصال بالتخلص منه سوف قم بتجميع المكالمة إلى Finalizer, جعل الاتصال التخلص من تعزيز الأداء.

نصائح أخرى

السياسة الأكثر أمانًا هي الاتصال دائمًا Dispose() على كائن إذا كان ينفذ IDisposable, ، إما بشكل صريح أو عبر كتلة باستخدام. قد تكون هناك حالات غير مطلوبة ولكن تسميتها على أي حال يجب ألا تسبب مشاكل (إذا تم كتابة الفصل بشكل صحيح). أيضًا ، لا تعرف أبدًا متى قد يتغير التنفيذ بمعنى أنه عندما لم تكن المكالمة مطلوبة من قبل ، فمن المؤكد أنها مطلوبة الآن.

في المثال الذي قدمته ، يمكنك إضافة إطار إضافي باستخدام كتلة للأمر ، وكذلك الحفاظ على الخارجي باستخدام كتلة للاتصال.

نعم ، يجب عليك ، حتى لو كان التنفيذ لا يفعل الكثير حاليًا ، فأنت لا تعرف كيف سيتم تغييره في المستقبل (إصدارات إطار عمل أحدث على سبيل المثال). بشكل عام ، يجب عليك التخلص من جميع الكائنات التي تنفذ IDisposable أن تكون على الجانب الآمن.

ومع ذلك ، إذا تم تأجيل العملية ولم تتحكم في النطاق الكامل (على سبيل المثال عند العمل بشكل غير متزامن ، أو عند إرجاع AN SqlDataReader أو هكذا) ، يمكنك تعيين ملف CommandBehavior إلى CloseConnection حتى أنه بمجرد الانتهاء من القارئ ، يتم إغلاق الاتصال/التخلص من ذلك بشكل صحيح.

يمكنك معرفة هذا النوع من الأشياء باستخدام العاكس أو dotpeek أو https://referencesource.microsoft.com/.

كان لدي حفر صغير (أود أن أقترح أن تحفر نفسك على الرغم من أن تكون متأكدًا تمامًا من بقية هذا على الرغم من أنني لم أحاول ذلك بجد) ويبدو أنه عندما تقتل اتصال لا يوجد أي أطفال مرتبطون مع هذا الاتصال. علاوة على ذلك ، لا يبدو في الواقع أن التخلص من الأمر يفعل ذلك كثيرًا. سيتم تعيين حقل لتفريغه ، وفصل نفسه عن حاوية (قد يمنع هذا تسرب الذاكرة المدارة) ورفع حدث (قد يكون هذا مهمًا ولكن لا يمكنني رؤية من يستمع إلى هذا الحدث).

في كلتا الحالتين ، من الممارسات الجيدة استخدام هذه الأشياء في كتلة باستخدام أو التأكد من التخلص منها باستخدام نمط التخلص في الكائن الذي يحمل الاتصال (إذا كنت تنوي التمسك بالأمر لفترة من الوقت).

في الممارسة العملية ، يمكنك تخطي Dispose. إنه لا يحرر أي موارد. حتى أنه لا يقمع الانتهاء منذ SQLCommand Constructor يفعل ذلك.

من الناحية النظرية ، يمكن لـ Microsoft تغيير التنفيذ لعقد مورد غير مُدار ، لكنني آمل أن يخرجوا مع واجهة برمجة تطبيقات تتخلص من Component الفئة الأساسية قبل وقت طويل من القيام بذلك.

في رأيي ، الدعوة Dispose لكليهما SqlConnection و SqlCommand هي الممارسة الجيدة ، استخدم الكود أدناه

using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString))
try{
    using(var command = connection.CreateCommand())
    {
       command.CommandText = "...";
       connection.Open();
       command.ExecuteNonQuery();
    }
}
catch(Exception ex){ //Log exception according to your own way
    throw;
}
finally{
    command.Dispose();
    connection.Close();
    connection.Dispose();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top