الجديد

التخلص من الكائنات

التخلص من الكائنات

في المقال ، ترميز مثيلات جديدة من الكائنات ، كتبت عن الطرق المختلفة لذلك الجديد يمكن إنشاء مثيلات الكائنات. المشكلة المعاكسة ، التخلص من كائن ما ، هي شيء لن تضطر إلى القلق بشأنه في VB.NET في كثير من الأحيان ... NET يتضمن تقنية تسمى جامع القمامة (GC) عادة ما تهتم بكل شيء خلف الكواليس بصمت وكفاءة. ولكن في بعض الأحيان ، عادةً عند استخدام تدفقات الملفات أو كائنات sql أو كائنات الرسومات (GDI +) (أي ، الموارد غير المدارة) ، قد تحتاج إلى السيطرة على التخلص من الكائنات في التعليمات البرمجية الخاصة بك.

أولا ، بعض الخلفية

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

(ويلل ... هذا صحيح تقريبا كل الوقت. تستطيع الاتصال الأسلوب GC.Collect وفرض دورة جمع القمامة ، ولكن السلطات تقول عالميا انها سيئة فكرة وغير ضرورية تماما.)

على سبيل المثال ، إذا كان الكود الخاص بك قد أنشأ زبون كائن ، قد يبدو أن هذا الرمز سوف يدمرها مرة أخرى.

العميل = لا شيء

لكن لا. (تعيين كائن إلى لا شيء يسمى عادة ، dereferencing الكائن.) في الواقع ، فهذا يعني فقط أن المتغير غير مرتبط بكائن بعد الآن. في وقت لاحق ، سوف تلاحظ GC أن الكائن متاح للتدمير.

بالمناسبة ، بالنسبة للكائنات المدارة ، لا شيء من هذا ضروري حقًا. على الرغم من أن كائنًا مثل الزر سوف يوفر طريقة التخلص ، فإنه ليس من الضروري استخدامه مع قلة من الأشخاص. تتم إضافة مكونات Windows Forms ، على سبيل المثال ، إلى كائن حاوية باسم المكونات. عند إغلاق نموذج ، يتم استدعاء طريقة التخلص منه تلقائيًا. عادةً ، ما عليك إلا أن تقلق بشأن أي شيء من هذا عند استخدام كائنات غير مُدارة ، وحتى بعد ذلك فقط لتحسين برنامجك.

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

Customer.Dispose () العميل = لا شيء

لأن GC يدمر كائنًا يتيمًا ، سواء أكنت تقوم بتعيين متغير الكائن إلى Nothing أم لا ، فهذا ليس ضروريًا حقًا.

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

في سلسلة GDI + ، عن طريق يتم وضع كتلة للاستخدام بشكل متكرر لإدارة تلك الكائنات الرسومات المزعجة. فمثلا…

باستخدام myBrush As LinearGradientBrush _ = New LinearGradientBrush (_ Me.ClientRectangle، _ Color.Blue، Color.Red، _ LinearGradientMode.Horizontal) End Using

myBrush يتم التخلص منه تلقائيًا عند تنفيذ نهاية الكتلة.

يعد نهج GC لإدارة الذاكرة تغييرًا كبيرًا عن طريقة VB6. تم تدمير كائنات COM (المستخدمة بواسطة VB6) عندما وصل عداد داخلي للمراجع إلى صفر. ولكن كان من السهل جدًا ارتكاب خطأ ، فكان العداد الداخلي مغلقًا. (نظرًا لأن الذاكرة كانت مرتبطة وغير متاحة للكائنات الأخرى عندما حدث هذا ، فقد كان يطلق عليها "تسرب الذاكرة".) بدلاً من ذلك ، يتحقق GC في الواقع لمعرفة ما إذا كان هناك شيء يشير إلى كائن ويدمره عندما لا توجد مراجع أخرى. يحتوي نهج GC على سجل جيد بلغات مثل Java وهو أحد التحسينات الكبيرة في .NET.

في الصفحة التالية ، ننظر إلى الواجهة IDisposable ... الواجهة التي يجب استخدامها عندما تحتاج إلى التخلص من الكائنات غير المدارة في التعليمات البرمجية الخاصة بك.

إذا قمت بتشفير كائن خاص بك يستخدم موارد غير مُدارة ، فيجب عليك استخدام IDisposable واجهة للكائن. تعمل Microsoft على تسهيل ذلك من خلال تضمين مقتطف الشفرة الذي ينشئ النمط المناسب لك.

--------
انقر هنا لعرض الرسم التوضيحي
انقر فوق الزر السابق في المستعرض الخاص بك للعودة
--------

يشبه الرمز الذي تمت إضافته (VB.NET 2008):

تطبق فئة ResourceClass IDisposable 'للكشف عن المكالمات الزائدة الخاصة التي تم التخلص منها باسم Boolean = False' التخلص من Subidable Subridable المحمي (_ _ التخلص ByVal باسم Boolean) إذا لم يكن Me.disposed ، ثم إذا تم التخلص ، ثم "حرر حالة أخرى" (الكائنات المدارة). End If 'حرر حالتك الخاصة (كائنات غير مُدارة). 'تعيين حقول كبيرة إلى فارغة. End If Me.disposed = True End Sub #Region "IDisposable Support" "هذا الكود الذي تمت إضافته بواسطة Visual Basic إلى" تطبيق النقش القابل للتصرف بشكل صحيح. Sub Sub Dispose () تطبق IDisposable.Dispose 'لا تقم بتغيير هذا الرمز. "ضع رمز التنظيف في" التخلص (ByVal التخلص كـ Boolean) أعلاه. تخلص (صواب) من GC.SuppressFinalize (Me) End Sub Overrides Sub Finalize () 'لا تقم بتغيير هذا الرمز. "ضع رمز التنظيف في" التخلص (ByVal التخلص كـ Boolean) أعلاه. التخلص (False) MyBase.Finalize () End Sub #End Region End Class

تخلص هو نمط تصميم مطور "فرض" تقريبًا في .NET. هناك حقًا طريقة واحدة صحيحة للقيام بذلك وهذه هي الحقيقة. قد تعتقد أن هذا الرمز يفعل شيئًا سحريًا. لا.

نلاحظ أولا أن العلم الداخلي استبعاده ببساطة دوائر قصيرة كل شيء حتى تتمكن من الاتصال التصرف (التخلص) كما تشاء.

الرمز…

GC.SuppressFinalize (البيانات)

... يجعل الكود أكثر فعالية من خلال إخبار GC بأن الكائن قد تم التخلص منه بالفعل (عملية "مكلفة" فيما يتعلق بدورات التنفيذ). وضع اللمسات الأخيرة محمي لأن GC يسميها تلقائيًا عند تدمير كائن. يجب عليك عدم الاتصال النهائي. المنطقية التخلص يخبر الكود ما إذا كان الكود قد بدأ التخلص من الكائن (صواب) أو ما إذا كان GC قد فعل ذلك (كجزء من وضع الصيغة النهائية الفرعية. لاحظ أن الكود الوحيد الذي يستخدم المنطقية التخلص هو:

إذا تخلص من ذلك "حرر حالة أخرى (الكائنات المدارة). إنهاء إذا

عند التخلص من كائن ما ، يجب التخلص من جميع موارده. عندما يتخلص أداة تجميع مجمعي البيانات المهملة من كائن ما ، يجب فقط التخلص من الموارد غير المدارة لأن أداة تجميع مجمعي البيانات المهملة تتولى تلقائيًا الموارد المدارة.

تتمثل الفكرة وراء مقتطف الشفرة هذا في إضافة رمز للعناية بالكائنات المدارة وغير المدارة في المواقع المشار إليها.

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

Over Subrides Sub Dispose (التخلص ByVal كـ Boolean) ، إن لم يكن Me.disposed ، ثم إذا كان التخلص ، فأضف الرمز الخاص بك إلى الموارد المدارة المجانية. End If 'أضف الكود الخاص بك إلى الموارد غير المدارة المجانية. End If MyBase.Dispose (التخلص) End Sub

يمكن أن يكون الموضوع ساحقًا بعض الشيء. الغرض من التفسير هنا هو "إزالة الغموض" عما يحدث بالفعل لأن معظم المعلومات التي يمكنك العثور عليها لا تخبرك!