هل هناك حاجة لتعيين الكائنات على لا شيء داخل وظائف VBA

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

سؤال

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

هل يتم فقدان المرجع وتحرير الذاكرة عند ترك نطاق الوظيفة، بغض النظر عن تعيين الكائنات على لا شيء؟

أي.هل من الضروري حقًا القيام بما يلي:

Set db = Nothing
Set record_set = Nothing
هل كانت مفيدة؟

المحلول

وVB يستخدم ما يسمى "حساب مرجع" جامع القمامة.

وأساسا، لحظة متغير يخرج من نطاق، وdecremented العداد مرجع على الكائن المشار إليه. عند تعيين مرجع كائن إلى متغير آخر، يتم زيادة عداد مرجع.

وعندما تصل العداد إلى الصفر، والهدف من ذلك هو على استعداد لجمع القمامة. سيتم الافراج عن موارد الكائن في أقرب وقت كما يحدث هذا. وهناك متغير محلي وظيفة على الأرجح مرجع كائن الذي لم يذهب أعلى من 1 عدد مرجع، حتى يعترض سيصدر الموارد عندما تنتهي المهمة.

ووضع متغير لNothing هو السبيل لخفض العداد الإشارة صراحة.

وعلى سبيل المثال، تقرأ في ملف، وتعيين متغير الكائن الملف إلى Nothing الحق بعد المكالمة ReadAll(). سيتم الافراج عن التعامل مع الملف على الفور، يمكنك أن تأخذ وقتك عملية محتوياته.

إذا لم تقم بتعيين لNothing، قد يكون التعامل مع الملف المفتوح يعد من الضرورة القصوى.

إذا لم تكن في نوع "يجب الافراج المورد الثمين" من الوضع، ببساطة السماح للمتغيرات الخروج من نطاق ما يرام.

نصائح أخرى

نادراً ما يكون جمع القمامة مثالياً.حتى في .NET، هناك أوقات يتم فيها تشجيعك بشدة على مطالبة النظام بالقيام بجمع البيانات المهملة مبكرًا.

لهذا السبب، أنا صراحة على حد سواء يغلق وتعيين ل لا شئ مجموعات السجلات عندما انتهيت منهم.

والسطر الأخير جدا من موضوع التعليمات ل " Recordset.Close "في DAO مساعدة مايكروسوفت ومرجع المطور Access هو هذا:

<اقتباس فقرة>   

و"بديل لأسلوب إغلاق هو   لتعيين قيمة متغير كائن   إلى لا شيء (مجموعة dbsTemp = لا شيء) ".

http://msdn.microsoft.com/en-us/library/ bb243098.aspx

ومع أخذ ذلك في الاعتبار، هذه المقالة من قاعدة المعارف ل Microsoft بعنوان "كيفية حماية قاعدة تشعر بالانتفاخ بعد استخدام كائنات الوصول إلى البيانات (DAO) "، يقول لك أنه يجب على مقربة صراحة إذا كنت لا تريد قواعد البيانات الخاصة بك إلى سخام. ستلاحظ أن هذه المادة غامضة قليلا عن التفاصيل؛ قسم "السبب" غير واضح، وتقريبا إلى نقطة يجري رطانة.

http://support.microsoft.com/kb/289562

<اقتباس فقرة>   

والأعراض: قاعدة بيانات Microsoft Access   بدأت تشعر بالانتفاخ (أو تنمو بسرعة في   حجم) بعد تطبيق الوصول إلى البيانات   الكائنات (DAO) لفتح السجلات.

     

والسبب: إذا لم يكن لاطلاق سراح   ذاكرة السجلات في كل مرة أن ل   حلقة من خلال رمز السجلات، DAO   قد إعادة ترجمة، وذلك باستخدام المزيد من الذاكرة و   زيادة حجم قاعدة البيانات.

     

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

وأخيرا، اسمحوا لي أن أضيف أن أكون قد تم العمل مع قواعد بيانات Access لمدة 15 عاما، وأنا دائما تقريبا اسمحوا لي المتغيرات مجموعة السجلات أعلن محليا تخرج من نطاق دون استخدام صراحة أسلوب إغلاق. أنا لم تفعل أي اختبار على ذلك، ولكن لا يبدو أن هذه المسألة.

من المفترض أن يكون تنظيف عندما ينتقل متغير خارج النطاق

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

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

لهذا السبب، وأظهر كلها أمثلة البرمجة MS VB دائما الأشياء التي أغلقت وتعيين إلى لا شيء. بحيث مقتطفات السيناريو يمكن أن تستخدم في بيئات مثل ASP الكلاسيكية حيث لم الكائنات لا تخرج من النطاق.

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

إذا كنت تجد نفسك الترميز ASP الكلاسيكية، أو تشغيل العمليات في نطاق عالمي لسبب آخر، ثم نعم، يجب الإفراج صراحة الكائنات.

وأنا عادة دائما وضع هذا في نهاية الإجراءات بلدي، أو الدعوة إلى "CloseRecordSet" دون معها في ما إذا كنت أستخدم منها مستوى الوحدة النمطية:

Private Sub Rawr()
On Error GoTo ErrorHandler

    'Procedural Code Here.

    ExitPoint:
        'Closes and Destroys RecordSet Objects.
        If Not Recset Is Nothing Then
            If Recset.State = 1 Then
                Recset.Close
                Conn.Close
            End If
            Set Recset = Nothing
            Set Conn = Nothing
        End If
        Exit Sub

    ErrorHandler:
        'Error Handling / Reporting Here.
        Resume ExitPoint
End Sub

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

وفعل ذلك بهذه الطريقة هو آمنة تماما في أنه يمكنك فقط صفعة في وانها لن تفعل إلا ما هو ضروري في ما يخص إغلاق أو تدمير الكائن السجلات / الصدد، أكان قد تم إغلاقه (نظرا ل خطأ وقت التشغيل أو مجرد إغلاقه وقت يا ينبغي، وهذا يجعل من مجرد متأكدا).

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

وهذه محاولة

If Not IsEmpty(vMyVariant) Then
    Erase vMyVariant
    vMyVariant = Empty
End If
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top