استدعاء التخلص () مقابل عندما يخرج كائن من النطاق / الطريقة
-
11-09-2019 - |
سؤال
لدي طريقة، والتي لديها try/catch/finaly
كتلة في الداخل. داخل كتلة المحاولة، أعلن SqlDataReader
كالآتي:
SqlDataReader aReader = null;
aReader = aCommand.ExecuteReader();
في ال finally
كتلة، الكائنات التي يتم التخلص منها يدويا هي تلك التي يتم تعيينها على مستوى الفصل. حتى الكائنات في الطريقة التي تنفذ IDisposable
, ، مثل SqlDataReader
أعلاه، هل يحصلون تلقائيا التخلص منها؟ Close()
يسمى aReader
بعد حلقة أثناء تنفيذ حلقة للحصول على محتويات القارئ (والتي يجب أن تكون Dispose()
كما يدعو هذا Close()
). إذا لم يكن هناك دعوة إلى Close()
, ، هل سيتم إغلاق هذا الكائن تلقائيا عند انتهاء الطريقة أو يخرج الكائن من النطاق؟
تحرير: أنا على علم using
بيان ولكن هناك سيناريوهات مربكة لي.
المحلول
لا، لا يتم التخلص من الكائنات تلقائيا عند الخروج من النطاق.
إنهم ليسوا مضمون حتى يتم التخلص منه إذا / عندما يتم جمع القمامة، على الرغم من أن الكثيرين IDisposable
كائنات تنفذ نهائيا "الاحتياط" للمساعدة في ضمان التخلص منها في نهاية المطاف.
أنت متهور لضمان أي IDisposable
يتم التخلص من الكائنات، ويفضل عن طريق لفها في using
منع.
نصائح أخرى
يجب عليك استخدام using {...}
كتلة لالتفاف الكائنات الخاصة بك في - Dispose()
الطريقة (التي بالنسبة إلى sqldatareader يمر إلى Close()
الطريقة) سيتم استدعاء عند انتهاء استخدام الكتلة. إذا كنت لا تستخدم using
, ، سوف الكائن ليس يتم التخلص منها تلقائيا عند الخروج من النطاق - سيكون الأمر متروكا للكائنات النهائية، إذا كان لديه واحد، للتخلص من الموارد عند جمع القمامة
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// ... do stuff
} // aReader.Dispose() called here
لا يجعل نمط التخلص من أي ضمانات حول الكائنات التي ستتصل بالتخلص منها كائنات أخرى؛ قد يحدث في بعض الأحيان، لكن يجب أن لا تهتم. بدلا من ذلك، تقع على عاتقك مسؤولية التأكد من التخلص منها () لجميع الكائنات غير القابلة للانتعراض. أفضل طريقة للقيام بذلك مع using
بيان. علي سبيل المثال:
using (SqlDataReader aReader = aCommand.ExecuteReader())
{
// your code
}
أنا متفق على كل ما سبق. يجب عليك التأكد من الاتصال Dispose()
نفسك، وأسهل طريقة لهذا هذا هو مع using
بيان (يمكنك أيضا أن تفعل هذا بنفسك في finally
كتلة - هذا أكثر سرعة، ولكن في بعض الأحيان ضرورية). إذا لم تقم بذلك، فيمكنك العثور على تطبيقك تسرب موارد غير مدارة مثل المقابض، أو حتى الذاكرة غير المدارة، خاصة إذا تم استخدام بعض مكونات COM بالكامل، أو يتم إجراء المكالمات في API Win32. من الواضح أن هذا يمكن أن يؤدي إلى مشاكل الأداء والاستقرار، وكذلك استخدام الموارد المفرطة.
فقط لأن الكائنات التي تنفذ IDisposable
"يجب" تنفيذ نهائي يسمي Dispose(bool disposing)
طريقة لتحرير الموارد غير المدارة، لا تضمن أن هذا سيحدث، لذلك يجب أن تعتمد بالتأكيد على ذلك. انظر، على سبيل المثال، http://msdn.microsoft.com/en-us/library/b1yfkh5e٪28VS.71٪29.aspx. لمزيد من المعلومات حول هذه النقطة.
أيضا، هناك شيء آخر في اعتباره في الاعتبار، هو أنه إذا كان من النوع الخاص بك يحتوي على أعضاء يمكن التخلص منها، فيجب أن ينفذ نوعك IDisposable
(ما لم تتم إدارة دورة حياة هؤلاء الأعضاء من قبل نوع آخر، مما قد يصبح من الواضح أنه قد يصبح فوضوي)، أو، إذا كنت تستخدم مثل هذه الأعضاء في طريقة واحدة فقط، أو لتنفيذ قطعة واحدة معينة من الوظائف، يجب عليك التفكير في جعلها متغيرات محلية / معلمات في الأساليب التي تستخدمها.
أنا أحترم من البيان "في الكتلة في النهاية، الكائنات التي يتم التخلص منها يدويا هي تلك التي يتم تعيينها على مستوى الفصل." بواسطة الكائنات المحددة على مستوى الفصل، هل تعني الحقول؟ ربما لا ينبغي أن تكون التخلص منها في غضون طريقة عادية، لأنه بعد ذلك، فإن وقت الحياة في الحقول لا يمكن التنبؤ بها، وتعتمد على الطرق التي حدثت فيها. سيكون من الأفضل تنفيذ Imnisaberable وتخلص من الحقول في طريقة التخلص الخاصة بك.
قد استخدام بيان مساعدة؟