تقييم الموضوع :
  • 0 أصوات - بمعدل 0
  • 1
  • 2
  • 3
  • 4
  • 5
إدارة المصادر والواجهة IDisposable
#1
كاتب الموضوع : samerselo



يقدم Visual Basic .net انعطافة جديدة في إدارة المصادر. حيث يوفر الـ CLR تقنية لإدارة المصادر تعرف باسم جمع النفايات Garbage Collection وذلك لتحرير المطور من معظم مهام إدارة الذاكرة. ولكن هذا لا يأتي بدون ثمن ولا يحررك بشكل كامل من التعامل مع إدارة الذاكرة. ففي بعض الحالات يجبرك جامع النفايات على أن تكون مدركا أكثر بخصوص العناصر التي يجب أن تقوم بالتخلص منها يدويا والتأكد من أن المصادر قد تم تحريرها بطريقة مناسبة. ولكن في أغلب الحالات لن تضطر للقلق حول متى يتم تدمير الأشياء.

في Visual Basic 6.0 عندما تصبح جميع المتغيرات التي تشير إلى شئ Object معين معينة إلى Nothing عندها يتم تحرير الذاكرة المرتبطة بهذه المتغيرات بشكل فوري. ويأخذ الـ CLR الآن هذه المسؤولية حول إدارة المصادر مما يمكن المطورين من التركيز على تحسين برامجهم عوضا عن كتابة الكثير من شيفرة إدارة الذاكرة.

وهذا يتطلب تغييرات في ممارسات كتابة الشيفرة. فمثلا عندما تضبط متغير ما إلى Nothing لا يتم تدمير الشئ Object مباشرة ولكن سوف يتم تدميره لاحقا وهذا ما يحدده جامع النفايات. وفي أغلب الحالات لا يجب أن يؤثر هذا على تطبيقك ولكن في بعض الحالات كبرنامج يقع تحت ضغط قلة مصادر النظام المتاحة يمكن أن يشكل معضلة حقيقية من ناحيتي الأداء والمرونة. ففي الحالات التي يكون فيها الأداء أساسي يكون من أول اهتماماتك إفراغ مصادر النظام فور فراغك من استخدامها.

أبق في ذهنك أن دورات جامع النفايات مكلفة. والفكرة تكمن في منع جامع النفايات من العمل بشكل متكرر كثيرا فكلما قمت بالتنظيف خلفك كلما تركت عمل أقل لجامع النفايات لعمله وبذلك تقوم بتحسين أداء برنامجك.

جامع النفايات The Garbage Collector

إذا كان التطبيق يستخدم مصادر غير مدارة Unmanaged Resources كتحديد ذاكرة خاصة أو مؤشرات الملفات أو عناصر أخرى من مصادر النظام فإن جامع النفايات في العادة لن يكون لديه فكرة عن كيفية تحرير تلك المصادر وبالرغم من أنه قد يكون قادرا على التعامل مع بعض هذه المصادر وربما لن يكون من الضروري تفريغهم بشكل دوري. ومن الهام أن تقوم ببعض التنظيف اليدوي وخاصة عندما تتعامل مباشرة مع ما يمثل بعض المصادر على الجهاز.
تجاوز Override الطريقة Object.Finalize وحرر بعض المصادر هناك ففي الحالة الافتراضية هذه الطريقة لا تفعل شيئا ولكن انتبه بما أن جامع النفايات يعمل باستخدام الطريقة Finalize فإن ذلك سيؤثر على الأداء فلا تقم باستخدامها إلا إذا كنت حقا بحاجة لاستخدامها. وحتى عندما يتم تجاوز Override الطريقة Finalize وتحرير المصادر لا يمكنك التحكم بمتى يقوم جامع النفايات ببدء عملية الجمع. مع أنه يمكنك دوما استدعاء System.GC.Collect ولكن لا يجب عليك القيام بذلك في بيئة الإنتاج. فإدارة مصادر CLR عملية معقدة والجامع يعرف متى يكون الوقت الأنسب لبدء دورة الجمع. كما أن أداء تطبيقك سيتأثر بشكل سئ إذا بدأت باستدعاء System.GC.Collect بشكل متكرر وأبق في ذهنك أن جامع النفايات يبدأ عندما يكون هناك حاجة لذاكرة مدارة وليس لديه تحكم حقيقي بالمصادر غير المدارة. حيث توفر لك الـ Framework حلا لهذه المشكلة وهي الواجهة IDisposable

الواجهة IDisposable

إذا كيف يمكنك معرفة إذا كان الشئ Object يحتاج إلى تنظيف إضافي؟ في الحقيقة الجواب سهل جدا فجميع الفئات Classes التي تقوم بتخصيص مصادر يجب تفريغها مباشرة يحب عليها أن تحقق الواجهة IDisposable وهي تحتوي على طريقة وحيدة

كود :
Public Interface IDisposable
Sub Dispose()
End Interface
إذا كانت الفئة Class التي تستخدمها تحقق هذه الواجهة يجب عليك استدعاء Dispose عندما تنتهي منها. أمر بسيط أليس كذلك؟ ولكن ما هي الفوائد من الواجهة IDisposable؟ الواجهة IDisposable تجعل من الممكن تحديد جميع الفئات Classes التي تخصص مصادر ثمينة وهي توفر آلية مبسطة يمكن الاعتماد عليها لتحرير جميع هذه المصادر. وكما ذكرنا سابقا العديد من الفئات في الـ Framework تحقق الواجهة IDisposable وهذا مثال يستخدم الفئة SqlConnection

كود :
Dim conn As New SqlConnection()
' Do Stuff
conn.Dispose()
ولكن ليس بالضرورة أن يكون هذا موثوقا فحدوث الأخطاء والاستثناءات متوقعا دائما لهذا يجب وضع استدعاء Dispose في قسم Finally في حلقة Try … Catch مما يضمن أن شيفرتك ستقوم بالتنظيف دائما حتى عند حدوث خطأ أو استثناء ما وبذلك يمكن إعادة كتابة الشيفرة السابقة بالشكل

كود :
Dim conn As SqlConnection
Try
conn = New SqlConnection()
' Do Stuff
Catch ex as Exception
' Handle Exception Here
Finally
conn.Dispose()
End Try
ولكن ماذا إذا احتجنا لتحقيق الواجهة IDisposable؟

تحقيق الواجهة IDisposable

إليك سؤال مثير للاهتمام: متى يجب على الفئة أن تحقق الواجهة IDisposable؟ هذه ثلاث حالات عامة يجب عليك فيها تحقيق الواجهة IDisposable في فئتك:
• عندما تحتوي فئتك على فئات أخرى تحقق الواجهة IDisposable
• عندما تحتوي فئتك على واجهات لأشياء COM
• عندما تحتوي فئتك على مقبض Handle لمصادر Win32 فعالة

وأبسط تحقيق للواجهة IDisposable يمكن أن يكون على الشكل

كود :
Public Class MyDisposableClass
Implements IDisposable

' Other members

Public Overloads Sub Dispose() Implements IDisposable.Dispose
' Release Your Resources Here
End Sub

End Class
ولكن أبسط تحقيق لا يكون دائما الأكثر وثوقية. ويمكن أن يبدو تحقيق أكثر اكتمالا على الشكل

كود :
Public Class MyDisposableClass
Implements IDisposable
Public Overloads Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me) ' No need call finalizer
End Sub

Protected Overridable Overloads Sub Dispose(ByVal disposing As Boolean)
If disposing Then
' Free managed resources
End If
' Free unmanaged resources
End Sub

Protected Overrides Sub Finalize()
Dispose(False)
End Sub
End Class
بالرغم مما قد يعتقده البعض تبقى إدارة الموارد جزء هام من عملية تطوير التطبيقات باستخدام Visual Basic .net وربما تفترض أنه على جامع النفايات القيام بجميع عمليات التنظيف وإدارة الذاكرة من أجلك بحيث يكون هذا الأمر صحيحا في أغلب الأحيان . وتكمن المشكلة هنا في أن التطبيق يمكن أن يستخدم مصادر معينة لا يمكن لجامع النفايات التعامل معها.مع أن جامع النفايات يمكنه التعامل مع معظم أمور إدارة الذاكرة لتطبيقك إلا أنه في بعض الحالات قد تضطر للقيام بعمل إضافي
و بسبب طبيعة جامع النفايات الغير قابلة للتحديد تظهر مشكلة حيث لا توجد أية ضمانات حول أية أشياء Objects سيتم تنظيفها في النهاية. حيث يشكل هذا الأمر مشكلة عندما تمزج معايير أداء صارمة مع أشياء Objects تستخدم ذاكرة غير مدارة كمقابض الملفات ورسوميات GDI+ ومقابض النوافذ و COM Objects وأشياء أخرى فإذا كان لديك تطبيق أو خدمة تتعامل مع الكثير من الطلبات المشابهة فقد تستنفذ موارد النظام بوقت قصير إن لم تتخلص منهم بسرعة. وبكلمات أخرى قد يسبق تطبيقك عملية التنظيف التي يقوم بها جامع النفايات ويتجاوز المصادر المتاحة من قبل النظام قبل أن يقوم جامع النفايات بتنظيف الأشياء الغير مستعملة.
من الواضح أن هذا الأمر ممكن أن يشكل مشكلة حقيقية ليس فقط بعملية التنظيف بذاتها ولكن بتحديد الأشياء التي تحتاج لتنظيف بشكل فوري. ويكون حل الـ CLR لهذه المشكلة بتقديمه الواجهة IDisopsable حيث تقوم هذه الواجهة بتحديد دالة وحيدة IDisposable.Dispose حيث تكون فكرة الواجهة IDisposable بسيطة جدا فإن كان شيئك Your Object يستخدم مصادر غير مدارة تستمر طوال فترة حياة ذلك الشئ Object يجب عليك تحقيق الواجهة IDisposable وتنطبق هذه القاعدة على فئاتك الخاصة Your Classes وأيضا على الفئات الموجودة سلفا ضمن الـ Framework
كما تجدر ملاحظة أن Visual Basic .net أو الـ CLR يجبرك على القيام بتنظيف الموارد الغير مدارة في فئاتك الخاصة أو تحقيق الواجهة IDisposable وتعتبر هذه هي الممارسة التي ينصح بها وبالتالي تضمن أن المطورين الآخرين سيعلمون أي الفئات تحتاج إلى عملية تنظيف إضافية
}}}
تم الشكر بواسطة:
#2

بالنسبة للمصادر المدارة والمصادر الغير مدارة

هناك طريقة سهلة جدا لمعرفة المصادر المدارة من المصادر الغير مدارة

المصادر المدارة ( حسب مفهوم الفريموورك ) Managed Resources هي تلك التي تحقق الواجهة IDisposable وبالتالي تكون المصادر الغير مدارة Unmanaged Resources هي تلك التي لا تحقق هذه الواجهة

مثلا إذا ذهبنا إلى مكتبة MSDN ونظرنا إلى الفئة Stream على سبيل المثال فستجد أن تعريفها Implementation يكون كما يلي

كود :
<SerializableAttribute> _
<ComVisibleAttribute(True)> _
Public MustInherit Class Stream _
Inherits MarshalByRefObject _
Implements IDisposable
إذا فهذه هي مصادر مدارة

وإذا نظرنا إلى الفئة StreamGeometry فسنجد أن تعريفها يكون كما يلي

كود :
<TypeConverterAttribute(GetType(GeometryConverter))> _
Public NotInheritable Class StreamGeometry _
Inherits Geometry
والفئة String أيضا هي مصادر غير مدارة


كما يمكن استخدام البرنامج التالي من مايكروسوفت لتسهيل التفريق بين الفئات التي تحقق الواجهة IDisposable أم لا
Microsoft FxCop 1.36
}}}
تم الشكر بواسطة:


المواضيع المحتمل أن تكون متشابهة .
الموضوع : الكاتب الردود : المشاهدات : آخر رد
  أهم طرق إدارة المخازن وتطبيقها على برنامج مخازن وارد ومنصرف Menna ahmeed 0 1,967 27-04-22, 12:52 PM
آخر رد: Menna ahmeed
  موضوع للنقاش- الواجهة IDisposable RaggiTech 2 2,621 05-10-12, 01:20 AM
آخر رد: RaggiTech
  الواجهة IComparable والواجهة IComparer RaggiTech 0 1,872 03-10-12, 01:02 AM
آخر رد: RaggiTech

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم