تمام أخي محمد هذا صحيح
مشكلتنا هنا هو أنه عندما يتم تدمير الكائن Sqlcommand أو Sqlconnection فإن الاتصال بقاعدة البيانات يبقى مفتوحا لذا كان على المبرمج الانتباه لإغلاق الاتصال قبل العودة من الإجراء
وعندما أتعامل مع اتصال بقاعدة السيكول سيرفر من خلال تطبيق asp.net فهنا لدي افتراضيا ما يدعى بـ connection pool يعني عدد الاتصالات الممكن أن تبقى مفتوحة محدود وبهذا نصل إلى مرحلة لم يعد هناك أي امكانية للاتصال حتى يصل أحد هذه الاتصالات إلى نهاية الوقت المسموح له بأن يكون IDLE وتنهيه قاعدة البيانات بشكل افتراضي
هناك حل للمشكل وذلك بزيادة حجم Connection Pool ولكن هذا سيؤثر على سرعة التطبيق والأداء فضلا عن استهلاك ذاكرة غير ضروري
هناك الكلاس الذي تحدث عنه الأخ silverlight وأنا اطمح لرؤية مثال عملي عنه وعن الطريقة التي يعمل بها[url=http://vb4arb.com/vb/user-1679.html][/url]
انا الى درسته ان جملة
Dispose()
تنهى الاتصال وتمسحه من الذاكرة
او تغلق الاتصال ب
كونكشن . close()
طيب هذا الحكي بعرفو بس وقت عم يتعلق الأمر بموضوع asp.net والسيكول سيرفر يللي عم يصير فعلي هو الحكي يللي بهذا الرابط
http://stackoverflow.com/questions/20203...connection
وأنا أساس علقتي بالمشكلة مع عدد الاتصالات الأقصى المسموح ببركة الاتصالات هو انني كنت معتمد على كلام الأخت ايمان والكلام الموجود في الرابط الذي تفضلت بوضعه أخ محمد
الكود التالي يوضح الشكل المبدئي للكلاس الذي تحدثت عنه
عليك أن تضيف له أي من الدوال التي تريدها
و يمكنك هنا ان تستخدم جملة Using و أنت مطمئن تماما أن Connection يتم اغلاقها
كود :
Imports System.Data.SqlClient
Public Class DisposableConnection
Implements IDisposable
Private _disposed As Boolean
Private _conn As SqlConnection
Private _command As SqlCommand
Public Sub New(connectionString As String)
_conn = New SqlConnection(connectionString)
_command = New SqlCommand
End Sub
Public ReadOnly Property Connection As SqlConnection
Get
Return _conn
End Get
End Property
Public ReadOnly Property Command As SqlCommand
Get
Return _command
End Get
End Property
Private Sub Flush()
_conn.Close()
End Sub
Private Sub CleanSqlObjects()
Flush()
If _conn IsNot Nothing Then
_conn.Dispose()
_conn = Nothing
End If
If _command IsNot Nothing Then
_command.Dispose()
_command = Nothing
End If
End Sub
Protected Overridable Sub Dispose(disposing As Boolean)
If _disposed Then
Return
End If
If disposing Then
CleanSqlObjects()
End If
_disposed = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
' GC.SuppressFinalize(Me)
End Sub
End Class
الكود التالي يوضح كيف يتم استخدام الكلاس
طبعا يمكنك ان تكتب اي إجراءات او تكتب اي دوال و تضيفها للكلاس كيفما شئت
أو تقوم بتعديل الكود كيفما شئت للتأكد من أن Connection تم إغلاقها
أنا فقط كتبت لك الفكرة المبدئية للكلاس
كود :
Dim s As String ' read connection fromm ConfigurationManager
Using conn As New DisposableConnection(s)
' do something
End Using
ملحوظة أخيرة
أعلم جيدا أن ما سوف أقوله سيزعج بعض الإخوة هنا
لكن انا ضد استخدام SQL او MS Access و أري أن كتابة بعض الكلاسات لحفظ البيانات باستخدام Stream أفضل كثيرا من الإعتماد علي قواعد البيانات التقليدية لأنه سيوفر الكثير من الصداع و سيعطي المبرمج قدرة أكبر علي التحكم بالبيانات كيفما يشاء
لكن الكثير من المبرمجين غالبا ما تختار الحلول الأسهل عموما وكما يقول المثل الشعبي عندنا في مصر كل شيخ و له طريقة
الامر اسهل من كده
اذا كان اسم كتغير الكونكشن conn
ونستخدم conn.close() و conn.open()
فقط هنعمل
conn.Dispose()
ويمكننا استخدام
msgbox(conn.State)
لمعرفة حالة الاتصال سواء كان مفتوح او مغلق او غير موجود
طيب بس وقت بتعمل dispose للكونكشن قبل من تعمل close لها ح توقع بالمشكل ضروري حتى نضمن عدم حدوث المشكل المطروح هو التأكد من إغلاق الاتصال قبل أن يتم التخلص من كائن الاتصال سواء بواسطة الأمر dispose أو بواسطة التصرف الطبيعي للأمر using
وهذا عن واقع تجربة
لماذا لا تنهى الاتصال مع سيشن من فى aspx
بالنسبة لردك المفروض تغلق الاتصال اولا وبعدين تحذفه من الذاكرة
اما بخصوص ثقل الموقع ده العادى بتاع aspx
بطيئ فى التنقل للصفحات ولكن آمن على البيانات
واخيرا هناك طريقة غير تقلدية بستخدمها فى الاخطاء ولكن كثير من الناس بشوف بيستخدموها فى شيئ محدد
وهى صائد الاخطاء try catch
بدلا من جملة اظهار رسالة الخطأ بعد الكاتش او الامساك بها
اكتب الكود المراد فعله ..... دى واحدة
الثانية استخدم جملة on Erurr go to
وحدد له المراد فعله بالظبط عند حدث خطأ
ودى افضل فلديشن للمبرمج مش لليوزر على فكرة
تقبلو رأى المتواضع