هل يحترم التشغيل المتداخل لـ COM حدود .NET AppDomain لتحميل التجميع؟

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

سؤال

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

ما أريد معرفته هو:هل هذا هو السلوك المتوقع، أم أنني أفعل شيئًا خاطئًا للتسبب في تحميل التجميعات ذات الصلة بـ COM في AppDomain الخاطئ؟يرجى الاطلاع على وصف أكثر تفصيلاً للحالة أدناه ...

يتكون التطبيق من 3 تجميعات:- EXE الرئيسي، نقطة الدخول للتطبيق.- common.dll ، يحتوي على icontroller فقط (في نمط iPlugin) - controller.dll ، يحتوي على فئة وحدة تحكم تنفذ icontroller و marshalbyrefobject.تقوم هذه الفئة بكل العمل وتستخدم التشغيل المتداخل لـ COM للتفاعل مع تطبيق آخر.

يبدو الجزء ذو الصلة من ملف EXE الرئيسي كما يلي:

AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);

يحتوي ملف common.dll على هذين الأمرين فقط:

public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
    ControllerRunResult Run();
}

ويحتوي ملف Controller.dll على هذه الفئة (والتي تستدعي أيضًا عناصر التشغيل المتداخل لـ COM):

public class Controller: IController, MarshalByRefObject

عند تشغيل التطبيق لأول مرة، يبدو Assembly.GetAssemblies() كما هو متوقع، حيث يتم تحميل common.dll في كل من AppDomains، ويتم تحميل Controller.dll فقط في مجال وحدة التحكم.بعد الاتصال بـ c.Run()، أرى أن التجميعات المتعلقة بعناصر التشغيل المتداخل لـ COM قد تم تحميلها في AppDomain الافتراضي، وليس في AppDomain الذي تجري منه عملية التشغيل المتداخل لـ COM.

لماذا يمكن أن يحدث هذا؟

وإذا كنت مهتمًا، فإليك القليل من الخلفية:

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

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

المحلول

لسوء الحظ، يتم تحميل مكون COM ضمن مساحة العملية وليس ضمن سياق AppDomain.وبالتالي، سوف تحتاج إلى هدم (تحرير وإلغاء تحميل) ملفات DLL الأصلية يدويًا (ينطبق على كل من COM وP/Invoc).إن مجرد تدمير نطاق التطبيق لن يفيدك، ولكن إعادة تشغيل العملية برمتها لا ينبغي أن يكون ضروريًا لإعادة تعيين حالة COM (مجرد إعادة إنشاء كائن (كائنات) COM يجب أيضًا أن تعمل بشكل طبيعي، وهذا يبدو وكأنه خطأ في كود موفري المكونات، ربما يمكنهم معالجتها؟)

مراجع

(تك نت) مساحة عنوان العملية

(MSDN) مجالات التطبيق

حدود (MSDN):العمليات ومجالات التطبيقات

نصائح أخرى

وهنا دليل على أن الجواب شون ويلسون هو الصحيح

ولا يصبح لديك تحكم MBR. إنشاء وكيل الصغير، الذي يحمل وحدة تحكم في المجال الثاني وبدء تشغيله. لن يتم تحميل هذا دلل تحكم الطريقة في المجال الأول.

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