|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
COM object that has been separated from its underlying RCW...On closing our App, we get following 'InvalidComObjectException': "COM object that has been separated from its underlying RCW cannot be used" The App has been upgraded from .Net1.1 to .Net2.0 a long time ago. Recently we started using the Application Framework, combined with a Splash Screen. About that moment we are having this issue. I thought the problem only existed while debugging, but now ,having a deployed version, it seems like Windows sometimes reoprts e fatal error on Exiting our app. Anyone some tips, because I don't know where to look anymore. Stack: [Managed to Native Transition] > System.Management.dll!System.Management.SinkForEventQuery.Cancel() + 0x3d bytes System.Management.dll!System.Management.ManagementEventWatcher.Stop() + 0x55 bytes System.Management.dll!System.Management.ManagementEventWatcher.Finalize() + 0x1b bytes DisAss: 0000003d mov esi,eax 0000003f mov ecx,dword ptr [ebp-24h] 00000042 call 000000D0 00000047 test esi,esi 00000049 jge 0000008F 0000004b mov eax,esi 0000004d sar eax,1Fh 00000050 mov edx,eax 00000052 mov eax,esi 00000054 and eax,0FFFFF000h 00000059 xor edx,edx 0000005b test edx,edx 0000005d jne 0000006F 0000005f cmp eax,80041000h 00000064 jne 0000006F 00000066 mov ecx,esi 00000068 call 000892C0 0000006d jmp 0000008F 0000006f test esi,esi 00000071 jge 0000008F 00000073 mov edx,41Fh 00000078 mov ecx,1 0000007d call 12957360 00000082 mov edx,dword ptr [eax+00000A54h] 00000088 mov ecx,esi 0000008a call 12A7B09B 0000008f mov dword ptr [ebp-1Ch],0 00000096 mov dword ptr [ebp-18h],0FCh 0000009d push 6751C827h 000000a2 jmp 000000A4 000000a4 mov ecx,dword ptr [ebp-24h] 000000a7 call 12957653 000000ac pop eax 000000ad jmp eax 000000af lea esp,[ebp-0Ch] 000000b2 pop ebx 000000b3 pop esi 000000b4 pop edi 000000b5 pop ebp 000000b6 ret 000000b7 mov dword ptr [ebp-18h],0 000000be jmp 000000AF > On closing our App, we get following 'InvalidComObjectException': "COM Hi,> object that has been separated from its underlying RCW cannot be used" I used to get this error often when trying to use an object that has been garbage collected. You should make sure you explicitly dispose and RELEASE all COM objects you are using, rather than relying on GC to do it for you. This means paying attention to return values from COM interfaces, which may be COM instances themselves. You should obviously follow the general pattern: Dim theObject as MyComObject = Nothing Try theObject = MyOtherComObject.GetAReferenceToSomething ... Catch Ex As Exception If theObject IsNot Nothing Then Marshal.ReleaseComObject ( theObject ) theObject = nothing End If End Try Also this error can occur if the application invoked to manage your com objects is destroyed before the objects are themselves in VB. This means you have VB objects alive and well but no underlying server to handle them. When creating a new instance the server should be automagically started, but in some instances this won't happen. Hi Robinson,
Thanks for your info. Pitty enough we use quite a few com-objects in that project, making it difficult to trace the problem. Also al com's are subclassed through our custom framework (making it more difficult to track). Do you have any idea on how to know which com is/are involved? TIA, Michael Show quoteHide quote "Robinson" wrote: > > > > > On closing our App, we get following 'InvalidComObjectException': "COM > > object that has been separated from its underlying RCW cannot be used" > > > > Hi, > > > I used to get this error often when trying to use an object that has been > garbage collected. You should make sure you explicitly dispose and RELEASE > all COM objects you are using, rather than relying on GC to do it for you. > This means paying attention to return values from COM interfaces, which may > be COM instances themselves. You should obviously follow the general > pattern: > > > > Dim theObject as MyComObject = Nothing > > Try > > theObject = MyOtherComObject.GetAReferenceToSomething > > ... > Catch Ex As Exception > > If theObject IsNot Nothing Then > Marshal.ReleaseComObject ( theObject ) > theObject = nothing > End If > > End Try > > > Also this error can occur if the application invoked to manage your com > objects is destroyed before the objects are themselves in VB. This means > you have VB objects alive and well but no underlying server to handle them. > When creating a new instance the server should be automagically started, but > in some instances this won't happen. > > > > > Hi Robinson, Hi,> > Thanks for your info. > Pitty enough we use quite a few com-objects in that project, making it > difficult to trace the problem. > Also al com's are subclassed through our custom framework (making it more > difficult to track). > Do you have any idea on how to know which com is/are involved? > To be honest I had such a headache with this kind of thing when I first started out with interop, I now overcompenstate and go into a paranoid panic whenever I instantiate anything COM related. The basic problem is you have a managed COM wrapper, but the underlying object it refers to has been destroyed. To get it clearer in your mind, here's a simple example: Dim xlApp As Microsoft.Office.Interop.Excel.Application Dim xlBook As Microsoft.Office.Interop.Excel.Workbook Dim xlSheet As Microsoft.Office.Interop.Excel.Worksheet xlApp = CType(CreateObject("Excel.Application"), Microsoft.Office.Interop.Excel.Application) xlBook = CType(xlApp.Workbooks.Add, Microsoft.Office.Interop.Excel.Workbook) xlSheet = CType(xlBook.Worksheets(1), Microsoft.Office.Interop.Excel.Worksheet) System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) ' This will fail - you released xlSheet above. xlSheet.Cells(2, 2) = "This is column B row 2" Now, how do you debug this in your application? It's very tough. First thing to do is look at where you are releasing COM objects. You must ensure there aren't any references to that object elsewhere in the application. Another way of doing this is to NEVER explicitly release the object, but to implement the IDisposable pattern in a wrapper class to do it for you on garbage collection. Then you can explicitly "dispose" of the object if you want, or let GC do it when all references have been released. I *always* implement the IDisposable pattern in any class I have that holds references to COM objects: Protected Overridable Sub DisposeManagedResources() End Sub Protected Overridable Sub DisposeUnmanagedResources() Marshal.ReleaseComObject ( xxxxxxx ) xxxxxx = nothing End Sub Public Sub Dispose() Implements IDisposable.Dispose If m_bDisposed Then Return End If Me.DisposeManagedResources() Me.DisposeUnmanagedResources() m_bDisposed = True GC.SuppressFinalize(Me) End Sub Protected Overrides Sub Finalize() If Not m_bDisposed Then Me.DisposeUnmanagedResources() End If End Sub Hi Robinson,
Thanks for all your help. I finally nailed down the 'COM'! I think I now do share your com-paranoia :-) Kind regards, Michael Show quoteHide quote "Robinson" wrote: > > > Hi Robinson, > > > > Thanks for your info. > > Pitty enough we use quite a few com-objects in that project, making it > > difficult to trace the problem. > > Also al com's are subclassed through our custom framework (making it more > > difficult to track). > > Do you have any idea on how to know which com is/are involved? > > > > Hi, > > To be honest I had such a headache with this kind of thing when I first > started out with interop, I now overcompenstate and go into a paranoid panic > whenever I instantiate anything COM related. The basic problem is you > have a managed COM wrapper, but the underlying object it refers to has been > destroyed. To get it clearer in your mind, here's a simple example: > > > Dim xlApp As Microsoft.Office.Interop.Excel.Application > Dim xlBook As Microsoft.Office.Interop.Excel.Workbook > Dim xlSheet As Microsoft.Office.Interop.Excel.Worksheet > > xlApp = CType(CreateObject("Excel.Application"), > Microsoft.Office.Interop.Excel.Application) > xlBook = CType(xlApp.Workbooks.Add, Microsoft.Office.Interop.Excel.Workbook) > xlSheet = CType(xlBook.Worksheets(1), > Microsoft.Office.Interop.Excel.Worksheet) > > System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet) > > ' This will fail - you released xlSheet above. > > xlSheet.Cells(2, 2) = "This is column B row 2" > > > Now, how do you debug this in your application? It's very tough. First > thing to do is look at where you are releasing COM objects. You must ensure > there aren't any references to that object elsewhere in the application. > Another way of doing this is to NEVER explicitly release the object, but to > implement the IDisposable pattern in a wrapper class to do it for you on > garbage collection. Then you can explicitly "dispose" of the object if you > want, or let GC do it when all references have been released. I *always* > implement the IDisposable pattern in any class I have that holds references > to COM objects: > > Protected Overridable Sub DisposeManagedResources() > > End Sub > > Protected Overridable Sub DisposeUnmanagedResources() > > Marshal.ReleaseComObject ( xxxxxxx ) > xxxxxx = nothing > > End Sub > > Public Sub Dispose() Implements IDisposable.Dispose > > If m_bDisposed Then > Return > End If > > Me.DisposeManagedResources() > Me.DisposeUnmanagedResources() > > m_bDisposed = True > > GC.SuppressFinalize(Me) > > End Sub > > Protected Overrides Sub Finalize() > > If Not m_bDisposed Then > Me.DisposeUnmanagedResources() > End If > > End Sub > > > >
System.Timers.Timer, thread synchronization issues
Thread.Sleep slowing down the whole application Play wavs in VB2005. Compression namespace for Array DataGridViewCell has lost its DataGridView - How to solve? Creating an array of textbox objects Able .NET ? Crystal Reports Logon Problem Don't see application events question about variables and subprocedure |
|||||||||||||||||||||||