Frage

Ich habe eine Windows Workflow-Anwendung, die Klassen verwendet ich für COM-Automatisierung geschrieben habe. Ich öffne Word und Excel aus meinen Klassen COM verwenden.

Ich bin zur Zeit der Umsetzung IDisposable in meinem COM Helfer und mit Marshal.ReleaseComObject (). wenn mein Workflow-schlägt jedoch fehl, wird die Methode Dispose () nicht aufgerufen wird und die Word- oder Excel-Griffe öffnen und meine Anwendung hängt bleiben.

Die Lösung für dieses Problem ist ziemlich einfach, aber anstatt es nur lösen, ich mag etwas lernen und einen Einblick in die richtige Weise zu gewinnen mit COM zu arbeiten. Ich interessiere mich für den „besten“ oder die effizienteste und sichersten Weg, um die Lebensdauer der Klassen zu behandeln, die die COM-Griffe besitzen. Patterns, Best Practices oder Beispielcode wäre hilfreich.

War es hilfreich?

Lösung

Ich kann nicht sehen, was Versagen Sie, dass nicht die Methode Dispose () aufruft. Ich habe einen Test mit einem sequenziellen Workflow, der nur eine Codeaktivität enthält, die nur eine Ausnahme und die Dispose () -Methode von meinem Workflow zweimal wirft genannt wird (dies ist wegen der Standard WorkflowTerminated Event-Handler). Überprüfen Sie den folgenden Code ein:

Program.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.");
            }
        }
    }

Bin ich etwas fehlt? In Bezug auf die Lebensdauer bezogenen Methoden einer Aktivität (und damit ein Workflow) Objekt, überprüfen Sie bitte diesen Beitrag: Activity "Lifetime" Methoden . Wenn Sie nur einen allgemeinen Artikel über entsorgen wollen, lesen Sie diese .

Andere Tipps

Grundsätzlich sollten Sie nicht auf der Hand Code verlassen am Ende der Arbeit Dispose () auf Ihrem Objekt aufzurufen. Sie haben wahrscheinlich so etwas wie dieses Recht jetzt:

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

Stattdessen müssen Sie Blöcke verwenden versuchen, eine Ausnahme zu fangen, die ausgelöst werden könnten, und an diesem Punkt entsorgen zu nennen. Dies ist der üblicher Weg:

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

Dies ist so gemeinsam, dass C # hat ein spezielles Konstrukt, das exakt das gleiche Code [siehe Anmerkung] erzeugt, wie oben gezeigt; das ist, was sollten Sie die meiste Zeit tun (es sei denn, Sie einige spezielle Objektbau Semantik haben, die eine manuelle Muster wie die oben leichter zu verarbeiten machen):

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

Bearbeiten :
HINWEIS: Der tatsächliche Code erzeugt wird, ist ein klein wenig komplizierter als das zweite Beispiel oben, weil sie auch einen neuen lokalen Bereich führt, der das Hilfsobjekt nicht verfügbar, nachdem der using Block macht. Es ist wie, wenn der zweite Codeblock durch {} s umgeben war. Das war für Klärung der Erläuterung weggelassen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top