المشاركات : 53
المواضيع 4
الإنتساب : Sep 2013
السمعة :
3
الشكر: 30
تم شكره 57 مرات في 17 مشاركات
حسبما أذكر فإنه عند تعريف متغير باستخدام الأمر using فإن البرنامج يقوم بالتخلص من المتغير بعد الخروج من الحلقة
و إذا استخدمناه لتعريف متغير لنقل من النوع SqlConnection أو SqlCommand فمن المفترض به التخلص من ذلك المتغير بعد الخروج من الحلقة
ولكن في واقع الأمر واجهت مشكلة في أحد تطبيقات asp.net مع vb.net التي أقوم بتنفيذها وهي انتهاء عدد الاتصالات المسموحة بقاعدة البيانات
ولدى مراجعة الكود وجدت أنني أستخدم مثلا Return cmd.ExecuteScalar للعودة من الـ Function والخروج من الوظيفة ولكن في الواقع أن الاتصال بقي مفتوحا بعد الخروج من الوظيفة بهذه الطريقة مع أنه نظريا خرج من حلقة using أيضا بواقع الحال
وكان الحل هو أن أسند القيمة إلى متغير ثم أغلق الاتصال يدويا ثم أعيد القيمة بواسطة return
فبرأيكم ما هو الوضع هنا ولماذا واجهت هذا الاشكال
فمع أنني حللت المشكل وأنهيت البرنامج إلا أنه مازالت قضية فكرية عالقة بالنسبة لي
المشاركات : 3
المواضيع 0
الإنتساب : May 2016
السمعة :
3
الشكر: 0
تم شكره 12 مرات في 4 مشاركات
المسألة ليست حالة استثنائية بقدر ماهي تعامل مع مصادر خارج تحكم الفجوال بيسيك نفسه
كما نعلم ان محرك إدارة البيانات مستقل عن الفجوال بيسيك، فعندما يتم طلب فتح الاتصال فان الفجوال بيسيك يرسل الطلب لمحرك إدارة البيانات سواء Access أو SQL Server، وسيضل محسوب هذا الاتصال في المحرك إلا أن تقوم بارسال طلب غلق أو تنتهي المدة المحددة في المحرك في حال عدم وجود نشاط.
من هنا نعلم أنه عند استخدام Using إنما يتم التعامل مع الكائن المنشأ في الفجوال بيسيك فقط، فإذا لم يتم طلب غلق الاتصال وتم الخروج من Using فإن الكائن المنشأ من SqlConnection قد تم تدميره في الفجوال بيسيك وأصبح البرنامج تحت رحمة مدة انتهاء الاتصال الخامل لغلق الاتصال من محرك إدارة البيانات.
لذلك يجب عدم استخدام Return مع اجراءات Execute الخاصة بطلب تنفيذ عملية ما من محرك البيانات وانما يتم وضعها في متغير مثل Dim res = cmd.ExecuteScalar وبعدها يتم طلب إغلاق الاتصال قبل تدمير الكائن SqlConnection ويمكن بعدها ارجاع القيمة مثل Return res
المشاركات : 53
المواضيع 4
الإنتساب : Sep 2013
السمعة :
3
الشكر: 30
تم شكره 57 مرات في 17 مشاركات
كلام الأخ في الرابط تقريبا نفس فكرة الأخ adham2016
تفسير منطقي من كلا الطرفين
المشاركات : 277
المواضيع 18
الإنتساب : Dec 2013
السمعة :
34
الشكر: 1057
تم شكره 2872 مرات في 215 مشاركات
كلام جميل و منطقي ... احب زي هذي المناقشات و الاسئله
شكرا ع الافاده
اسم معرفي : محمد يحيى
المشاركات : 1,486
المواضيع 101
الإنتساب : Sep 2012
السمعة :
127
الشكر: 71
تم شكره 6155 مرات في 1035 مشاركات
07-05-16, 03:28 PM
(آخر تعديل لهذه المشاركة : 07-05-16, 03:31 PM {2} بواسطة silverlight.)
الأخ سامر
أرجو منك أن تكتب لنا الكود الذي تسبب في المشكلة؟
لأني أعتقد أن المشكلة تكمن في عدم وضوح الرؤية لمتي يتم إستخدام جملة Using
خاصة أن هذه الجملة مصممة للتعامل مع اي كلاس يقوم يكون IDisposable interface جزء منه
أيضا لنضع في الاعتبار أنه لا يمكن تخصيص متغيرات و استردادها أثناء استخدام جملة Using و البديل الأمثل هنا هو استخدام جملة Try Catch Finally End Try خاصة مع الدوال Functions
أو أن يتم بناء كلاس أساسه IDisposable interface
ويكون SqlConnection و Sqlcommand جزء منه بحيث يتم كتابة الدوال داخل الكلاس الجديد ثم و أخيرا يتم اغلاق Connection و عمل Dispsoe لحميع المتغيرات الموجودة في الكلاس الجديد من خلال الحدث Dispsose
و بعد ذلك يمكنك أن تستخدم الكلاس الجديد مع جملة Using بشكل عادي لأنه بعد الانتهاء من جملة using سيتم إغلاق Connection
المشاركات : 1,486
المواضيع 101
الإنتساب : Sep 2012
السمعة :
127
الشكر: 71
تم شكره 6155 مرات في 1035 مشاركات
بعد رؤية الدالة المستخدمة أعقتد أن كيفية و اسلوب كتابة الكود وخاصة مع جملة Using لا يصلح معه ان نسترد من خلاله أي متغيرات
جملة Using قد تكلفك الكثير في تلك الحالة و البدبل الأمثل جملة Try Catch Finally End Try
أو ان كان ضروريا أن تستخدم جملة Using تحديدا في تلك الحالة انت تحتاج لبناء كلاس منفرد تضع به جميع الدوال و يكون اساسه IDisposable Interface
عموما أن أردت يمكنني ان أضع لك الكود الخاص بهذا الكلاس لاحقا و عليك أنت أن تكمل بناء الكلاس و تضيف له الدوال التي تريدها
المشاركات : 53
المواضيع 4
الإنتساب : Sep 2013
السمعة :
3
الشكر: 30
تم شكره 57 مرات في 17 مشاركات
ياريت لو تضع لنا مثالا يوضح فكرة الكلاس الذي تتحدث عنه