سؤال

DataSet و DataTable كلاهما ينفذ غير قابل للانهيار، لذلك، من خلال أفضل الممارسات التقليدية، يجب أن أسمي أساليب التخلص منها ().

ومع ذلك، من ما قرأته حتى الآن، فإن DataSet و Datatable لا تملك في الواقع أي موارد غير مدارة، لذلك لا تفعل ذلك كثيرا.

بالإضافة إلى ذلك، لا أستطيع استخدام فقط using(DataSet myDataSet...) لأن DataSet لديه مجموعة من databables.

لذلك، أن تكون آمنا، سأحتاج إلى التكرار من خلال mydataset.Tables، والتخلص من كل من databables، ثم التخلص من مجموعة البيانات.

لذلك، هل يستحق المشعرات بالاتصال بالتخلص () على جميع مجموعات البيانات الخاصة بي و Databables؟

إضافة:

بالنسبة لأولئك الذين يعتقدون أن DataSet يجب التخلص منها: بشكل عام، فإن نمط التخلص هو استخدامه using أو try..finally, ، لأنك تريد أن تضمن أنه سيتم استدعاء التخلص ().

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

أو، هل تشير إلى أنني فقط استدعاء mydataset.dispose ()، ونسيان التخلص من databables في mydataset.tables؟

هل كانت مفيدة؟

المحلول

فيما يلي بعض المناقشات التي تشرح لماذا لا يلزم التخلص من DataSet.

للتخلص أو عدم التخلص من؟:

توجد طريقة التخلص من DataSet إلا بسبب التأثير الجانبي للميراث - بمعنى آخر، فلا تفعل شيئا مفيدا في وضع اللمسات الأخيرة.

يجب أن يتم التخلص من كائنات DataTable و DataSet؟ يتضمن بعض التفسير من MVP:

لا تحتوي مساحة اسم System.Data (Adonet) على موارد غير مدارة. لذلك ليس هناك حاجة للتخلص من أي من تلك طالما أنك لم تقم بإضافتك بشيء خاص به.

فهم طريقة التخلص من البيانات ومجموعات البيانات؟ لديه مع تعليق من السلطة سكوت ألين:

في براتيس نادرا ما نتخلص من مجموعة البيانات لأنها توفر القليل من الفائدة "

لذلك، توافق الآراء هناك لا يوجد حاليا سبب وجيه للاتصال بالتخلص على مجموعة بيانات.

نصائح أخرى

تحديث (1 ديسمبر 2009):

أود تعديل هذه الإجابة وتنازل أن الإجابة الأصلية معيبة.

التحليل الأصلي هل تنطبق على الكائنات التي تتطلب الانتهاء - والنقطة التي لا ينبغي قبول الممارسات على السطح دون فهم دقيق ومتعمق يقف.

ومع ذلك، اتضح أن مجموعات البيانات، DataViews، Databables قمع الانتهاء في منشئهم - هذا هو السبب في أن دعوة التخلص منها () عليها لا تفعل شيئا صراحة.

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

(أن مؤلفي .NET سيعتني بمعالجة الانتهاء من الانتهاء من الأنواع التي تحتل عادة معظم الذاكرة تتحدث بأهمية هذه الممارسة بشكل عام لأنواع نهائية.)

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

بعد الكثير من القراءة، إليك فهمي:

إذا كان الكائن يتطلب الانتهاء، فهذا استطاع تشغل الذاكرة لفترة أطول مما يحتاجه - إليك السبب: أ) أي نوع يحدد المدمرة (أو يرث من نوع يحدد المدمرة) تعتبر نهاية لها؛ ب) عند التخصيص (قبل تشغيل المنشئ)، يتم وضع مؤشر في قائمة انتظار الانتهاء؛ ج) الكائن النهائي يتطلب عادة 2 مجموعات لاستخدامها (بدلا من المعيار 1)؛ د) قمع الانتهاء لا يزيل كائن من قائمة انتظار الانتهاء (كما ذكرت بواسطة! Finalizequeue في SOS) هذا الأمر مضلل؛ مع العلم أن الكائنات الموجودة في قائمة انتظار النهج النهائي (في حد ذاتها) ليست مفيدة؛ معرفة الكائنات الموجودة في قائمة انتظار الانتهاء ولا تزال تتطلب الانهيار ستكون مفيدة (هل هناك أمر لهذا؟)

تحول قمع الانتهاء، يتحول قليلا في رأس الكائن الذي يشير إلى وقت التشغيل أنه لا يحتاج إلى استدعاء نهضه (لا يحتاج إلى نقل قائمة الانتظار الفعالة)؛ يبقى في قائمة انتظار الانتهاء (ولا يزال بالإبلاغ عنها! Finalizequeue في SOS)

يتم تشغيل فئات DataTable، DataSet، DataView جميعها في Marshalbyvaluecomponent، وهي كائن نهائي يمكن (يحتمل) التعامل مع الموارد غير المدارة

  • لأن DataTable، DataSet، DataView لا تقدم موارد غير مدارة، فإنها قمع الانتهاء في منشئتهم
  • في حين أن هذا هو نمط غير عادي، إلا أنه يحرر المتصل من الاضطرار إلى القلق بشأن استدعاء المتصل بعد الاستخدام
  • هذا، وحقيقة أن DataTables يمكن تقاسمها عبر مجموعات البيانات المختلفة، من المحتمل أن تكون مجموعات البيانات لا تهتم بالتخلص من Databables الأطفال
  • هذا يعني أيضا أن هذه الكائنات ستظهر تحت! Finalizequeue في SOS
  • ومع ذلك، يجب أن تظل هذه الكائنات مستردة بعد مجموعة واحدة، مثل نظرائهم غير النهائي

4 (مراجع جديدة):

الإجابة الأصلية:

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

بلا شك، والتخلص يجب ان يكون دعا إلى أي كائنات نهائية.

DataTables. نكون نهائي.

استدعاء التخلص بشكل كبير يسرع استصلاح الذاكرة.

marshalbyvaluecomponent. المكالمات gc.suppressFinalize (هذا) في التخلص منها () - تخطي هذا يعني الاضطرار إلى انتظار العشرات إذا لم يكن مئات المجموعات Gen0 قبل استصلاح الذاكرة:

مع هذا الفهم الأساسي للانتهاء، يمكننا بالفعل استنتاج بعض الأشياء المهمة للغاية:

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

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

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

خذها من شخص ما شهد 100s من ميغابايت من DataTables غير المرجعية في Gen2: هذا مهم للغاية وفائنا تماما من خلال الإجابات على هذا الموضوع.

مراجع:

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

2 - http://vineetgupta.spaces.live.com/blog/cns! 8de4bdc896bee1ad1ad04.Entry. http://www.dotnetfunda.com/articles/article524-net-best-practice-no-2-improve-grovage-collection-performance-using-finalizedispos-pattern.aspx.

3 - http://codeidol.com/csharp/net-framework/inside-the-clr/automatic-memory-management/

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

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

ما إذا كان التخلص () فعلا يفعل شيئا ما أو لا يعتمد على فئة معينة. في حالة وجود مجموعة بيانات، يتم تخلص من التنفيذ () من marshalbyvaluecomponent. يزيل نفسها من الحاوية والمكالمات التي تم التخلص منها. رمز المصدر أدناه (تفكيكه مع عاكس .NET):

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        lock (this)
        {
            if ((this.site != null) && (this.site.Container != null))
            {
                this.site.Container.Remove(this);
            }
            if (this.events != null)
            {
                EventHandler handler = (EventHandler) this.events[EventDisposed];
                if (handler != null)
                {
                    handler(this, EventArgs.Empty);
                }
            }
        }
    }
}

هل تنشئ DataTables نفسك؟ نظرا لأنه لا يلزم التطابقة من خلال أطفال أي كائن (كما في DataSet.Tables)، لأن مهمة الوالد للتخلص من جميع أعضاء الأطفال.

بشكل عام، القاعدة هي: إذا قمت بإنشائها، فإنها تنفذ نهايات، وتخلصها. إذا لم تخلقها، فلا تتخلص من ذلك، فهذه هي مهمة الكائن الأصل. ولكن قد يكون لكل كائن قواعد خاصة، تحقق من الوثائق.

بالنسبة ل .NET 3.5، فإنه يقول صراحة "التخلص منها عند عدم استخدام بعد الآن"، لذلك هذا ما سأفعله.

أنا استدعاء التخلص في أي وقت ينفذ كائن غير قابل للانتعراض. انها هناك لسبب ما.

يمكن أن تكون مجموعات البيانات هجلة هائلة. في أقرب وقت يمكن وضع علامة عليها لتنظيف، كلما كان ذلك أفضل.

تحديث

لقد مرت 5 سنوات منذ الإجابة على هذا السؤال. ما زلت أتفق مع إجابتي. إذا كان هناك طريقة متابعة، فيجب أن يتم استدعاؤها عند الانتهاء من الكائن. تم تنفيذ واجهة IDISPOWER لسبب ما.

إذا كانت نيتك أو سياق هذا السؤال عبارة عن مجموعة من القمامة حقا، فيمكنك ضبط مجموعات البيانات و DataTables إلى Null بشكل صريح أو استخدم الكلمة الأساسية باستخدام والسماح لهم بالخروج من النطاق. التخلص لا يفعل الكثير كما قال Tetraneutron ذلك في وقت سابق. ستجمع GC كائنات بيانات لم تعد تتم الإشارة إليها وأيضا تلك التي هي خارج نطاقها.

أتمنى أن أقدم الناس في التصويت على كتابة تعليق قبل تحويل الإجابة.

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

حاول استخدام وظيفة واضحة (). إنه يعمل بشكل رائع بالنسبة لي للتخلص.

DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();

لا حاجة للتخلص () لأن DataSet يرث من فئة marshalbyvaluecomponent وتنفيذ marshalbyvaluecomponent

بادئ ذي بدء، أود التحقق من أن التخلص من dataSet. ربما تستخدم العاكس من Redgate سيساعد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top