Vra

Ek het 'n Windows Workflow program wat klasse Ek het geskryf vir COM outomatisering gebruik. Ek is die opening van Word en Excel uit my klasse met behulp COM.

Ek is tans besig met IDisposable in my COM helper en met behulp van Marshal.ReleaseComObject (). Maar as my Workflow versuim, die metode ontslae () is nie genoem en die Woord of Excel hanteer bly oop en my aansoek hang.

Die oplossing vir hierdie probleem is redelik eenvoudig, maar eerder as om net op te los nie, wil ek graag iets leer en insig in die regte manier om te werk met COM. Ek is op soek na die "beste" of mees doeltreffende en veiligste manier om die lewensiklus van die klasse wat die COM handvatsels besit hanteer. Patrone, beste praktyke, of voorbeeld kode sou nuttig wees.

Was dit nuttig?

Oplossing

Ek kan nie sien wat versuim jy dit beteken die metode ontslae () nie noem. Ek het 'n toets met 'n opeenvolgende workflow dat slegs 'n kode aktiwiteit wat net gooi 'n uitsondering en die metode ontslae () van my workflow is twee keer genoem (dit is as gevolg van die standaard WorkflowTerminated event handler) bevat. Gaan die volgende kode:

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

Mis ek iets? Met betrekking tot die lewensiklus verwante metodes van 'n aktiwiteit (en gevolglik van 'n Workflow) voorwerp, kyk hierdie post: aktiwiteit" Lifetime ". As jy wil net 'n generiese artikel oor die verwydering, kyk hierdie .

Ander wenke

Basies, jy moet nie staatmaak op hand-kode te vervreem () op jou voorwerp noem aan die einde van die werk. Jy het waarskynlik iets soos hierdie oomblik:

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

In plaas daarvan, moet jy gebruik probeer blokke om enige uitsondering wat kan veroorsaak word vang en noem ontslae op daardie stadium. Dit is die kanonieke manier:

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

Dit is so algemeen dat C # is 'n spesiale konstruk wat genereer presies dieselfde kode [sien nota] as hierbo; dit is wat jy die meeste van die tyd moet doen (tensy jy 'n paar spesiale konstruksie voorwerp semantiek wat 'n handleiding patroon maak soos die bogenoemde makliker om mee te werk):

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

Edit :
NOTA: Die werklike kode gegenereer is 'n klein bietjie meer ingewikkeld as die tweede voorbeeld hierbo, want dit ook stel 'n nuwe plaaslike omvang dat die helper voorwerp beskikbaar na die using blok maak. Dis soos as die tweede-kode blok is omring deur {} 's. Wat weggelaat vir verduidelik van die verduideliking.

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top