callbackOnCollectedDelegate MDA

callbackOnCollectedDelegateإدارة التصحيح assهوtant (MDA) هو تنشيطها إذا مفوض هو تنظيم من تعليمات برمجية المدارة لم إدارته كمؤشر دالة رد اتصال هو وضعها في ذلك مؤشر الدالة بعد تجميع البيانات المهملة المفوض.

الأعراض

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

الفشل هو لا consهوtent، أحياناً الاستدعاء دالة من مؤشر نجاح وأحيانا يفشل. فشل قد يحدث فقط ضمن تحميل كثيف أو تشغيل رقم عشوائية من المحاولات.

السبب

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

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

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

الدقة

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

التأثير تشغيل وقت التشغيل

عندما يتم تنظيم التفويضات كـ مؤشرات دالة، يخصص وقت التشغيل تعليمة برمجية للتحويل لا الانتقال من مدارة إلى مدارة. Th هو تعليمة برمجية للتحويل هو ما تعليمات برمجية غير مُدارة فعلياً يستدعي قبل المفوض المدارة هو استدعاء أخيرا. بدون callbackOnCollectedDelegateMDA ممكنة، وتعليمات برمجية غير مدارة لتنظيم هو تم الحذفها عند المفوض هو التي تم تجميعها. مع callbackOnCollectedDelegateMDA ممكنة، وتعليمات برمجية غير مدارة لتنظيم هو لا مباشرة تم الحذف عند المفوض هو التي تم تجميعها. بدلاً من ذلك، يتم الاحتفاظ المثيلات 1000 الأخير النشاط ب الافتراضي والمتغيرة لتنشيط MDA عند استدعاء. تعليمة برمجية للتحويل هو أخيرا تم الحذف بعد جمعها 1,001 المفوضون منظم أكثر.

الإخراج

تقارير MDA اسم نوع المفوض التي تم جمعها قبل محاولة القيام استدعاء تشغيل مؤشر دالة غير المدار الخاص به.

التكوين

يلي مثال يعرض خيارات تكوين تطبيق. يقوم بتعيين عدد thunks يحافظ MDA النشاط إلى 1500. افتراضي listSizeالقيمة هي 1000 الحد الأدنى هو 50 والحد الأقصى هو 2.000.

<mdaConfig>
  <assistants>
    <callbackOnCollectedDelegate listSize="1500" />
  </assistants>
</mdaConfig>

مثال

يوضح المثال التالي موقف يمكن تنشيطها MDA هذا:

// Library.cpp : Defines the unmanaged entry point for the DLL application.
#include "windows.h"
#include "stdio.h"

void (__stdcall *g_pfTarget)();

void __stdcall Initialize(void __stdcall pfTarget())
{
    g_pfTarget = pfTarget;
}

void __stdcall Callback()
{
    g_pfTarget();
}
// ---------------------------------------------------
// C# Client
using System;
using System.Runtime.InteropServices;

public class Entry
{
    public delegate void DCallback();

    public static void Main()
    {
        new Entry();
        Initialize(Target);
        GC.Collect();
        GC.WaitForPendingFinalizers();
        Callback();
    }

    public static void Target()
    {        
    }

    [DllImport("Library", CallingConvention = CallingConvention.StdCall)]
    public static extern void Initialize(DCallback pfDelegate);

    [DllImport ("Library", CallingConvention = CallingConvention.StdCall)]
    public static extern void Callback();

    ~Entry() { Console.Error.WriteLine("Entry Collected"); }
}

راجع أيضًا:

المرجع

MarshalAsAttribute

gcUnmanagedToManaged MDA

المبادئ

تشخيص الأخطاء مع المساعدين التصحيح مدارة

تنظيم إمكانية التشغيل المتداخل

موارد أخرى

إمكانية التشغيل المتداخل