استدعاء التخلص () مقابل عندما يخرج كائن من النطاق / الطريقة

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

سؤال

لدي طريقة، والتي لديها 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 وتخلص من الحقول في طريقة التخلص الخاصة بك.

قد استخدام بيان مساعدة؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top