none
COM RCW reference count in an AppDomain RRS feed

  • Question

  • I have an Outlook AddIn that I'm loading separate AppDomains into. I'm then passing Outlook (COM RCW) objects into these AppDomains. The basics of this work just fine, but reference counts seem to come unstuck when I fetch another object reference from within the AppDomain.

    For a straight-forward example, I've got a button on a Mail.Compose ribbon, with a click handler. This code is executing within the primary Outlook add-in AppDomain.

    var execAsm = System.Reflection.Assembly.GetExecutingAssembly();
    var loadUri = new Uri(execAsm.CodeBase);
    string loadDir = System.IO.Path.GetDirectoryName(loadUri.LocalPath);
    
    // Create app-domain
    AppDomainSetup appSetup = new AppDomainSetup();
    appSetup.ApplicationBase = loadDir;
    System.Security.PermissionSet permSet = 
       new System.Security.PermissionSet(
       System.Security.Permissions.PermissionState.Unrestricted);
    var myDomain = AppDomain.CreateDomain("MyDomain", null, appSetup, permSet, null);
    
    // Get instance from app-domain
    dynamic addInPoint = myDomain.CreateInstanceAndUnwrap(
        assemblyName: "ClassLibrary1",
        typeName: "ClassLibrary1.Class1");
    
    // Do work on mail item
    Outlook.MailItem currentMail = 
        Outlook.MailItem)Globals.ThisAddIn.Application.ActiveInspector()
        .CurrentItem;
    addInPoint.DoWork(currentMail);
    
    // Clean-up
    Marshal.ReleaseComObject(currentMail);
    currentMail = null;

    And the Class implementation below. To be clear, this is only ever executed within a separate AppDomain.

    public void DoWork(Outlook.MailItem mail)
    {
        mail.Save();
        mail.To = "foobar@test.com";
    
        var propAccessor = mail.PropertyAccessor;
        Marshal.ReleaseComObject(propAccessor);
        propAccessor = null;
    }

    The usage scenario is straight forward:

    1. Click "New Email".
    2. Click the add-in button in the ribbon.
    3. Close the Email - choose "No" on unsaved changes prompt.
    4. Close Outlook - receive two more "unsaved changes" prompts for the same item, indicative of an un-released reference to the mail item.

    The issue appears to lie in the call to mail.PropertyAccessor, and subsequentReleaseComObject. This should be releasing the reference, and the refcount returned fromReleaseComObject is zero, but clearly there's still a reference, as removing those lines from theDoWork method results in no "unsaved changes" prompt at step 4. For what it's worth, moving up to the more brute-force Marshal.FinalReleaseComObject method makes no difference.

    There's also nothing intrinsically wrong with the mail.PropertyAccessor code. Move it out of theDoWork method and up into the ribbon button click event handler, and as one would expect, there are no unsaved changes prompts at step 4.

    What's going on here?

    Monday, August 26, 2013 8:52 PM