views:

108

answers:

1

I have the below method for spellchecking in my in house app. As a new programmer this was pieced together through multiple sources and tweaked until it worked for me.

As I grow and learn I come across things that make me go, hmm. Like this SO post,How to properly clean up Excel interop objects in C#, that talks about proper Interop cleanup.

I noticed it mentions repeatedly the use of Marshal.FinalReleaseComObject() or Marshal.ReleaseComObject().

My question is this, based on the code below do I need this as well? Thanks

        public string CheckSpelling(string text)
    {
        Word.Application app = new Word.Application();
        object nullobj = Missing.Value;
        object template = Missing.Value;
        object newTemplate = Missing.Value;
        object documentType = Missing.Value;
        object visible = false;
        object optional = Missing.Value;
        object savechanges = false;
        app.ShowMe();

        Word._Document doc = app.Documents.Add(ref template, ref newTemplate, ref documentType, ref visible);

        doc.Words.First.InsertBefore(text);
        Word.ProofreadingErrors errors = doc.SpellingErrors;

        var ecount = errors.Count;
        doc.CheckSpelling(ref optional, ref optional, ref optional, ref optional, 
            ref optional, ref optional, ref optional, ref optional, ref optional, 
            ref optional, ref optional, ref optional);
        object first = 0;
        object last = doc.Characters.Count - 1;
        var results = doc.Range(ref first, ref last).Text;
        doc.Close(ref savechanges, ref nullobj, ref nullobj);
        app.Quit(ref savechanges, ref nullobj, ref nullobj);

        return results;
    }
+1  A: 

I would say definitely. You should always use Marshal.ReleaseComObject to clean up unmanaged COM references in .NET code.

Steve Danner
So I would be looking at adding these 3 lines? `Marshal.ReleaseComObject(doc); Marshal.ReleaseComObject(app); Marshal.ReleaseComObject(errors);`
Refracted Paladin
Yes, I would say that should take care of it. You'll want to make sure you wrap the existing code in a try...finally block and release the COM objects in the finally block to ensure they actually do get cleaned up.
Steve Danner
Thanks! Last clarification, and I will look into it myself as well, do I not need `Marshal.FinalReleaseComObject()` as well? I am unsure how that differs is al.
Refracted Paladin
According to the documentation `Marshal.FinalReleaseComObject()` is the same as invoking `Marshal.ReleaseComObject()` in a loop until it returns 0 indicating it was released successfully. Thus it's safer and better practice to use `Marshal.FinalReleaseComObject()`.
Keith