ما هي الطريقة الأكثر فعالية للتعامل مع دورة حياة كائن مع interop COM ؟

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

سؤال

لدي ويندوز سير العمل تطبيق يستخدم الطبقات كتبت COM الأتمتة.أنا فتح Word و Excel من الفصول باستخدام COM.

أنا حاليا تنفيذ IDisposable في بلدي COM مساعد باستخدام المشير.ReleaseComObject().ومع ذلك ، إذا فشل سير العمل ، Dispose() الأسلوب لا يتم يسمى Word أو Excel مقابض البقاء مفتوحة طلبي معلق.

حل هذه المشكلة بسيط جدا ، ولكن بدلا من حلها ، أود أن تتعلم شيئا و التبصر في الطريق الصحيح للعمل مع COM.أنا أبحث عن "أفضل" أو الأكثر كفاءة والأكثر أمانا طريقة للتعامل مع دورة حياة الفئات التي تملك COM مقابض.أنماط أفضل الممارسات ، أو نموذج التعليمات البرمجية قد تكون مفيدة.

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

المحلول

أنا لا يمكن أن نرى ما الفشل يجب أن لا يدعو طريقة Dispose ().أنا قدمت اختبار مع متتابعة سير العمل تحتوي على رمز النشاط الذي يطرح استثناء و طريقة Dispose() من سير العمل يسمى مرتين (لأن هذا هو المعيار WorkflowTerminated معالج الحدث).تحقق من التعليمات البرمجية التالية:

البرنامج.cs

    class Program
    {
        static void Main(string[] args)
        {
            using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())
            {
                AutoResetEvent waitHandle = new AutoResetEvent(false);
                workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) 
                {
                    waitHandle.Set();
                };
                workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)
                {
                    Console.WriteLine(e.Exception.Message);
                    waitHandle.Set();
                };

                WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));
                instance.Start();

                waitHandle.WaitOne();
            }
            Console.ReadKey();
        }
    }

Workflow1.cs

    public sealed partial class Workflow1: SequentialWorkflowActivity
    {
        public Workflow1()
        {
            InitializeComponent();
            this.codeActivity1.ExecuteCode += new System.EventHandler(this.codeActivity1_ExecuteCode);
        }

        [DebuggerStepThrough()]
        private void codeActivity1_ExecuteCode(object sender, EventArgs e)
        {
            Console.WriteLine("Throw ApplicationException.");
            throw new ApplicationException();
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Here you must free your resources 
                // by calling your COM helper Dispose() method
                Console.WriteLine("Object disposed.");
            }
        }
    }

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

نصائح أخرى

في الأساس يجب أن لا تعتمد على اليد رمز الاتصال Dispose() على وجوه الخاص بك في نهاية العمل.ربما لديك شيء من هذا القبيل الآن:

MyComHelper helper = new MyComHelper();
helper.DoStuffWithExcel();
helper.Dispose();
...

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

MyComHelper helper = new MyComHelper();
try
{
    helper.DoStuffWithExcel();
}
finally()
{
    helper.Dispose();
}

هذا هو لذلك الشائع أن C# خاص بناء على أن يولد نفس الكود [انظر الحاشية] كما هو مبين أعلاه ؛ هذا هو ما يجب أن تقوم به أكثر من مرة (إلا إذا كان لديك بعض وجوه دلالات البناء التي تجعل من دليل نمط مثل ما ورد أعلاه أسهل للعمل مع):

using(MyComHelper helper = new MyComHelper())
{
    helper.DoStuffWithExcel();
}

تحرير:
ملاحظة:الفعلية البرمجية التي تم إنشاؤها هو قليلا أكثر تعقيدا من المثال الثاني أعلاه ، لأنه كما يقدم الجديد النطاق المحلي الذي يجعل كائن مساعد غير متوفرة بعد using كتلة.انها مثل إذا كان رمز الثاني كان محاطا كتلة { }'s.التي حذفت من أجل توضيح من التفسير.

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