|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
RegisterAssembly, CreateComInstanceFrom and IsCOMObjectRegistrationServices.RegisterAssembly, then I am instantiating that class via CreateObject, then I am testing if the object is a COM instance via Type.IsCOMObject. Surprisingly (to me) the return value is False. This is a problem for me, because I am using managed code to write a OWC spreadsheet addin, and memory allocated by the addin is not freed when the spreadsheet is destroyed. I wanted to explicitly invoke InteropServices.Marshal.ReleaseComObject, but it is failing, presumably because the object returned by CreateObject() is, in some way, not a COM class. Can anyone explain why the IsCOMObject is returning False, and what I might be able to do to make it return True? Sub Main() Dim lvType As System.Type = GetType(ComClassTest) Dim lvRegistrationServices As New Runtime.InteropServices.RegistrationServices() lvRegistrationServices.RegisterAssembly(lvType.Assembly, Runtime.InteropServices.AssemblyRegistrationFlags.None) Runtime.InteropServices.RegistrationConnectionType.SingleUse) Try Dim lvObject As System.Object = Microsoft.VisualBasic.CreateObject(lvRegistrationServices.GetProgIdForType(lvType)) Debug.Assert(True = lvObject.GetType.IsCOMObject, "CreateObject creates a COM object") ' this assertion fails Finally lvRegistrationServices.UnregisterAssembly(lvType.Assembly) End Try End Sub Corey,
>Can anyone explain why the IsCOMObject is returning False, and what I might When two .NET objects communicate in the same process you don't go>be able to do to make it return True? through COM interop, so you don't have an RCW reference and therefore IsCOMObject is false. Why do you think ReleaseComObject could help you here? The garbage collector is responsible for cleaning up mamanged resources. Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. Mattias,
> Why do you think ReleaseComObject could help you here? The garbage I may be going about this the wrong way, but here's the explanation of what > collector is responsible for cleaning up managed resources. lead me to where I am. I'm sorry that it is so long, but it boils down to this question: Is it possible to make a .NET class appear as a COM class inside of .NET so that ReleaseComObject would actually work? Using ReleaseComObject was a suggestion from a respected source in another newsgroup (microsoft.public.office.developer.web.components). I'm using the Microsoft Office Web Components (OWC10) spreadsheet control. That control has an AddIn method which expects a COM Automation addin object, which is just an instance of a COM class. Once registered via AddIn, the methods may be used in spreadsheet formulas. Because of the nature of the formulas I'm creating, it made sense to write my classes in .NET, and then register the assembly via RegisterAssembly, and then instantiate the class via CreateObject. This all works great. The problem starts when I destroy the spreadsheet control. The add-in, and all the resources it allocated, are never freed. So far, the only way I can get the memory freed is by using a separate ApplicationDomain, which isn't a practical solution in this case. During my testing, I instantiate a form which contains the ActiveX spreadsheet control, I invoke the AddIn method on that spreadsheet. Once the form is closed, I set the form reference to null, then invoke GC.Collect(). At this point, the amount of memory unreleased grows with the amount of memory I consume via my test addin method, which simply creates and populates a DataTable of a specified size with bogus data. While searching for a solution to this problem, Alvin Bruney (MVP) suggested that I try to us ReleaseComObject. It seems like a reasonable idea, but the problem is, the object returned by CreateObject cannot be destroyed/released via ReleaseComObject. The most puzzling thing about this is that the method in the class instance is registered with the spreadsheet (it really works), so it must have been converted to a COM class, but there's something special going on, which I think you are alluding to here: > When two .NET objects communicate in the same process you don't go My guess is that the .NET managed object, which is instantiated as a COM > through COM interop, so you don't have an RCW reference and therefore > IsCOMObject is false. object and registered with the spreadsheet as an AddIn, cannot be GC'd because the spreadsheet is somehow not releasing the Addin. Not knowing how to proceed, I was hoping that invoking ReleaseComObject would work. So, my new question is, is it possible to make a .NET class appear as a COM class inside of .NET so that ReleaseComObject would actually work? Show quote "Mattias Sjögren" <mattias.dont.want.spam@mvps.org> wrote in message news:u96VNbfTGHA.4976@TK2MSFTNGP11.phx.gbl... > Corey, > >>Can anyone explain why the IsCOMObject is returning False, and what I >>might >>be able to do to make it return True? > > When two .NET objects communicate in the same process you don't go > through COM interop, so you don't have an RCW reference and therefore > IsCOMObject is false. > > Why do you think ReleaseComObject could help you here? The garbage > collector is responsible for cleaning up mamanged resources. > > > Mattias > > -- > Mattias Sjögren [C# MVP] mattias @ mvps.org > http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com > Please reply only to the newsgroup. Corey,
>Is it possible to make a .NET class appear as a COM class inside of .NET so The short answer is no, it's not possible.>that ReleaseComObject would actually work? Mattias -- Mattias Sjögren [C# MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup. |
|||||||||||||||||||||||