GOTCHA 66 Using interface pointers after calling ReleaseComObject() will fail


GOTCHA #66 Using interface pointers after calling ReleaseComObject() will fail

As I mentioned in Gotcha #65, "Release of COM object is confusing," there are a few problems with using the ReleaseComObject() method. In this gotcha I discuss one of those issuesdealing with multiple interfaces.

When working with COM components you often use more than one interface. For instance, say you have a component that exposes two interfaces, IMyComp and IMyComp2. When using these two interfaces, which one should you release? Those of you who have worked with COM in C++ or VB6 are probably saying, "Both of them, of course." But in .NET, that is not the case. You can't continue to use a COM component after you have called ReleaseComObject() on any of the interface references to that component.

Let's pursue an example where a COM component supports the two interfaces IMyComp and IMyComp2, with one method in each, Method1() and Method2(). Example 8-2 shows the .NET code to access it.

Example 8-2. Working with multiple interfaces of a COM component

C# (COMInterfaces)

 using System; namespace COMCompUser {     class Test     {         [STAThread]         static void Main(string[] args)         {             Console.WriteLine("Creating object");             MyCOMCompLib.IMyComp theMyComp                 = new MyCOMCompLib.MyCompClass();             MyCOMCompLib.IMyComp2 theMyComp2                 = (MyCOMCompLib.IMyComp2) theMyComp;             Console.WriteLine("Calling Method1");             theMyComp.Method1();             Console.WriteLine("Releasing the object");             System.Runtime.InteropServices.Marshal.ReleaseComObject(                 theMyComp);             Console.WriteLine("Calling Method2");             theMyComp2.Method2();             Console.ReadLine();         }     } } 

VB.NET (COMInterfaces)

 Module Test     Sub Main()         Console.WriteLine("Creating object")         Dim theMyComp As MyCOMCompLib.IMyComp _             = New MyCOMCompLib.MyCompClass         Dim theMyComp2 As MyCOMCompLib.IMyComp2 _             = CType(theMyComp, MyCOMCompLib.IMyComp2)         Console.WriteLine("Calling Method1")         theMyComp.Method1()         Console.WriteLine("Releasing the object")             System.Runtime.InteropServices.Marshal.ReleaseComObject( _                 theMyComp)         Console.WriteLine("Calling Method2")         theMyComp2.Method2()         Console.ReadLine()     End Sub End Module 

In this example, you obtain two references to the COM component, one for each of its interfaces. You then release the first reference using ReleaseComObject(). When you invoke Method2() using the IMyComp2 interface reference, you get a NullReferenceException, as shown in Figure 8-4.

Figure 8-4. Output from Example 8-2


The exception is raised from the RCW because, as its name implies, ReleaseComObject() has released the object. Working with a COM component using the interface reference in .NET is different from C++ and VB6.

Understand the issues related to proper cleanup and the state of the RCW. This is another reason to isolate the interaction with the component as discussed in Gotcha #70, "Spattering access to COM components makes code hard to maintain."

IN A NUTSHELL

If you have obtained multiple interfaces on a COM component, do not use any of the references after calling ReleaseComObject. The RCW disconnects from the COM object when you call ReleaseComObject(). Understand that calling ReleaseComObject() is not the same as calling IUnknown's Release() method.

SEE ALSO

Gotcha #65, "Release of COM object is confusing" and Gotcha #70, "Spattering access to COM components makes code hard to maintain."



    .NET Gotachas
    .NET Gotachas
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 126

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net