none
A Question of Coding Technique RRS feed

  • Question

  • I have a rather complex Word 2010 Add-in developed with VS 2010 VB .Net and I’m wondering about a coding technique that I use and if it is appropriate … “a good practice or not.”

    In the add-in there are about 36 public class dialog forms, 12 code modules with public subroutines, and then of course public and private code routines in the ThisAddin class module itself.

    In practice I reference Word in the following manner:

    Imports Word = Microsoft.Office.Interop.Word

    And in the various forms and modules I use private local references to the application:

    Dim wApp as Word.Application = Globals.ThisAddin.Application

    What I’m wondering if there are any negative implications for this approach that I have taken?  Also before closing a form or exiting a code module, should I execute a Marshal. ReleaseComObject(wApp) or because it is a private local variable, is it already taken care of when the form is closed or the code module exited?

    I have made a practice of releasing local Word.Document and Word.Range referenced objects but I’m wondering if I should do the same with the local Word.Application object as well?

    I have used local references to the Word.Application object versus making it a Shared Public object variable so I could avoid typing ThisAddin.wApp on every command in the various forms and modules.  Is this a good practice or not?


    Kind Regards, Rich ... http://greatcirclelearning.com
    Thursday, November 3, 2011 2:27 PM

Answers

  • Hi Rich

    I can't answer the other questions, but

    <<Also before closing a form or exiting a code module, should I execute a Marshal. ReleaseComObject(wApp) or because it is a private local variable, is it already taken care of when the form is closed or the code module exited?>>

    Generally, you should NOT be using Marshal.ReleaseComObject. If you're deriving this from Globals.ThisAddin.Application then this is where the COM pointer is stored. It's not "your business" to worry about releasing that at the COM level - VSTO takes care of it.

    Whether or not your local variable is Private isn't key so much as whether it's declared within a procedure - in which case it goes out of scope and will be garbage-collected when the procedure finishes, or whether it's class-level, in which case its life-time will (and should be) the life-time of the class instance. Once the class instance is released (set to Nothing), then all its variables should be released for GC, as well. If you want to release it specifically, then set it to Nothing in the Finalizer for the class (after releasing the other Word objects).


    Cindy Meister, VSTO/Word MVP
    Thursday, November 3, 2011 2:39 PM
    Moderator
  • Hello,

    You need to release the COM objects that you create in your code. You definitely must not release ThisAddin.Application: it was given to you and you must return it back. That's becuse you must not release COM objects created outside of your code.

    It seems however that the last "must" doesn't apply to COM objects that your code accepts in parameters of events. It would be reasonable for the event source to release such COM objects after the event procedure is finished:

    void aVstoEventHandler(object comObject)
    {
        if (yourEventHandler != null)
        {
            try
            {
                yourEventHandler(comObject);
            }
            catch(Exception ex)
            {
                 errorHandler(ex);
            }
        }
        Marshal.ReleaseComObject(comObject);
    }
    

    Nevertheless, I remember how in a new VSTO add-in project you added empty event handlers for some events and Outlook hanged in the memory after you closed its UI. The solution was to release COM objects passed to such event handlers. It was as if in the event procedure above they didn't call ReleaseComObject. I'm not sure whether they've changed this behavior or not.


    Regards from Belarus (GMT + 2),

    Andrei Smolin
    Add-in Express Team Leader
    Thursday, November 3, 2011 5:26 PM

All replies

  • Hi Rich

    I can't answer the other questions, but

    <<Also before closing a form or exiting a code module, should I execute a Marshal. ReleaseComObject(wApp) or because it is a private local variable, is it already taken care of when the form is closed or the code module exited?>>

    Generally, you should NOT be using Marshal.ReleaseComObject. If you're deriving this from Globals.ThisAddin.Application then this is where the COM pointer is stored. It's not "your business" to worry about releasing that at the COM level - VSTO takes care of it.

    Whether or not your local variable is Private isn't key so much as whether it's declared within a procedure - in which case it goes out of scope and will be garbage-collected when the procedure finishes, or whether it's class-level, in which case its life-time will (and should be) the life-time of the class instance. Once the class instance is released (set to Nothing), then all its variables should be released for GC, as well. If you want to release it specifically, then set it to Nothing in the Finalizer for the class (after releasing the other Word objects).


    Cindy Meister, VSTO/Word MVP
    Thursday, November 3, 2011 2:39 PM
    Moderator
  • Hello,

    You need to release the COM objects that you create in your code. You definitely must not release ThisAddin.Application: it was given to you and you must return it back. That's becuse you must not release COM objects created outside of your code.

    It seems however that the last "must" doesn't apply to COM objects that your code accepts in parameters of events. It would be reasonable for the event source to release such COM objects after the event procedure is finished:

    void aVstoEventHandler(object comObject)
    {
        if (yourEventHandler != null)
        {
            try
            {
                yourEventHandler(comObject);
            }
            catch(Exception ex)
            {
                 errorHandler(ex);
            }
        }
        Marshal.ReleaseComObject(comObject);
    }
    

    Nevertheless, I remember how in a new VSTO add-in project you added empty event handlers for some events and Outlook hanged in the memory after you closed its UI. The solution was to release COM objects passed to such event handlers. It was as if in the event procedure above they didn't call ReleaseComObject. I'm not sure whether they've changed this behavior or not.


    Regards from Belarus (GMT + 2),

    Andrei Smolin
    Add-in Express Team Leader
    Thursday, November 3, 2011 5:26 PM
  • Hi Cindy Hi Andrei,

    As always, thank you for the information and what you do to help others.

     


    Kind Regards, Rich ... http://greatcirclelearning.com
    Saturday, November 5, 2011 11:19 AM