لا يمكنني مساعدة نفسي في نشر هذا ، على الرغم من أنه ليس إجابة مباشرة على السؤال.
هناك مقال رائع من MSKB من العصور الذهبية في كوم: معلومات: أوصاف وأعمال نماذج خيوط OLE. لا يزال هناك ، ولديه كل المعلومات ذات الصلة. النقطة المهمة هي أنه لا ينبغي أن تقلق بشأن ما إذا كان هناك حشد أم لا ، إذا اتبعت القواعد. فقط قم بتسجيل كائنك كـ ThreadingModel=Both
, ، تجميع المارشالر الحراري مع CoCreateFreeThreadedMarshaler
, وينجز. سيفعل com الحشد إذا لزم الأمر ، بأفضل طريقة ممكنة. اعتمادًا على نموذج شقة العميل ، قد يتلقى رمز العميل المؤشر المباشر إلى الواجهة الخاصة بك ، إذا كان يتبع القواعد أيضًا.
أي واجهة "أجنبية" قد تتلقاها عندما يتم استدعاء طريقة الواجهة الخاصة بك ، ستكون صالحة في نطاق المكالمة ، لأنك تبقى على نفس الموضوع. إذا كنت لا تحتاج إلى تخزينها ، فهذا كل ما يهم.
ومع ذلك ، إذا كنت بحاجة إلى تخزين الواجهة "الغريبة" ، فإن الطريقة الصحيحة للقيام بذلك هي تخزينها باستخدام CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
:
لتخزينه:
- أدخل القسم الحرج ؛
- مكالمة
CoMarshalInterThreadInterfaceInStream
وتخزين IStream
مؤشر في حقل عضو ؛
- اترك القسم الحرج ؛
لاسترداده
- أدخل القسم الحرج ؛
- مكالمة
CoGetInterfaceAndReleaseStream
لاسترداد الواجهة
- مكالمة
CoMarshalInterThreadInterfaceInStream
وتخزينه مرة أخرى IStream
لأي استخدام في المستقبل
- اترك القسم الحرج ؛
- استخدم الواجهة في نطاق المكالمة الحالية
لإطلاق سراحه:
- عندما لم تعد بحاجة إلى الاحتفاظ بها ، ما عليك سوى إطلاق المخزنة
IStream
(داخل القسم الحرج).
إذا كان الكائن "الأجنبي" قد تم تربيته حرًا أيضًا ، وكانت الأشياء تحدث داخل نفس العملية ، فمن المحتمل أن تتعامل مع مؤشر الواجهة المباشر بعد CoGetInterfaceAndReleaseStream
. ومع ذلك ، يجب ألا تضع أي افتراضات ، ولا تحتاج حقًا إلى معرفة ما إذا كان الكائن الذي تتعامل معه هو الكائن الأصلي أو وكيل Com Marshaller.
يمكن تحسين ذلك قليلاً باستخدام CoMarshalInterface
ث/ MSHLFLAGS_TABLESTRONG
/ CoUnmarshalInterface
/ IStream::Seek(0, 0)
/ CoReleaseMarshalData
بدلاً من CoGetInterfaceAndReleaseStream
/CoGetInterfaceAndReleaseStream
, ، لإلغاء تشغيل الواجهة نفسها عدة مرات كما هو مطلوب دون إطلاق الدفق.
سيناريوهات التخزين المؤقت الأكثر تعقيدًا (وربما أكثر كفاءة) ممكنة ، والتي تتضمن تخزين الخيوط المحلية. ومع ذلك ، أعتقد أن هذا سيكون مبالغة. لم أفعل أي توقيت ، لكنني أعتقد أن النفقات العامة CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
هو حقا منخفضة.
ومع ذلك ، إذا كنت بحاجة إلى الحفاظ على حالة ذلك يخزن أي موارد أو كائنات قد تتطلب تقارب الخيط, ، بخلاف واجهات كوم المذكورة أعلاه ، أنت لا يجب ضع علامة على هدفك ThreadingModel=Both
أو تجميع FTM.