هل يقوم Garbage Collector بتدمير الكائنات غير المرجعية مؤقتًا أثناء الاستدعاءات غير المتزامنة في .NET؟

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

سؤال

تخيل أنني سأقوم بإجراء مكالمة غير متزامنة في .NET، أي.HttpWebRequest.BeginGetResponse، ولا تتم الإشارة إلى كائن HttpWebRequest على نطاق أوسع.هل سيدمرها جامع القمامة ويسبب مشاكل؟

رمز المثال:

using System;
using System.Net;

public class AsyncHttpWebRequest
{
    void Main()
    {
        var Request = HttpWebRequest.Create("http://www.contoso.com");
        var result = Request.BeginGetResponse(GetResponseCallback, null);
    }

    private void GetResponseCallback(IAsyncResult AsyncResult)
    {
        // Do Something..
    }
}

إصدار بديل (مع تمرير الطلب باعتباره AsyncState):

using System;
using System.Net;

public class AsyncHttpWebRequest
{
    void Main()
    {
        var Request = HttpWebRequest.Create("http://www.contoso.com");
        var result = Request.BeginGetResponse(GetResponseCallback, Request);
    }

    private void GetResponseCallback(IAsyncResult AsyncResult)
    {
        // Do Something..
    }
}
هل كانت مفيدة؟

المحلول

ويعتبر كائن حي وغير مؤهلة لجمع القمامة إذا أي موضوع مباشرة على مرجع إلى ذلك، أو إذا هو المشار إليها ثابت (مباشر أو غير مباشر في كل الحالات).

في كل من الأمثلة API المتزامن تبقي إشارة إلى طلبك (داخل تجمع مؤشرات الترابط حيث استقرت عمليات IO عدم التزامن) وذلك لن يكون القمامة جمع حتى يكمل.

نصائح أخرى

لا، جامع القمامة لن يسبب لك مشاكل.

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

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

يتم تضمين كل مؤشر ترابط قيد التشغيل - بما في ذلك الخيط (السلاسل) الذي يعالج مكالمات Async في قائمة الجذور.

إذا كائن لا يوجد لديه المراجع بقدر ما GC قلقة فإنك لم تعد قادرة على على إشارة إلى ذلك. لذلك لا يمكن أن يكون كائن <م> مؤقتا لايوجد إشارة إلى ذلك.

(وهذا يفترض شيئا متستر مثل الرمز لعب ألعاب غير المدارة أو غير الآمنة)

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

في رمز المثال الأول، لماذا تقوم بإنشاء طلب إذا كنت لا تستخدمه؟

على أي حال، في حالة عدم وجود مرجع (مباشر أو غير مباشر) لكائن من أي من الكائنات الموجودة حاليًا في نطاق GC يمكن اجمعه.

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

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