I’m having trouble with my COM component written in .NET throwing warnings that look like:
Context 0x15eec0 is disconnected. No
proxy will be used to service the
request on the COM component. This may
cause corruption or data loss. To
avoid this problem, please ensure that
all contexts/apartments stay alive
until the application is completely
done with the RuntimeCallableWrappers
that represent COM components that
live inside them.
It looks like this is caused by my GUI thread calling functions in the COM thread without necessary syncronization. For reference I’m using the guidelines set in http://msdn.microsoft.com/en-us/library/ms229609%28VS.80%29.aspx for creating my GUI thread in the COM component.
My code looks something like:
class COMClass {
// this is called before SomeMethod
public void Init() {
ComObject comObject = new ComObject(); // this is imported from a TLB
// I create my GUI thread and start it as in the MSDN sample
Thread newThread = new Thread(new ThreadStart(delegate() {
Application.Run(new GUIForm(comObject));
}));
}
public void SomeMethod(){
comObject.DoSomething(); // this is where the error occurs
}
}
class GUIForm : Form {
ComObject com;
public GUIForm(ComObject com) {comObject = com;}
public void SomeButtonHandler(object sender, EventArgs e) {
comObject.SomeMethod(); // call on the GUI thread but the com object is bound to the COM thread...
}
}
Is there an established method for dealing with this? Calls to the GUI are no problem (Invoke/BeginInvoke) but calling the other way seems to be more difficult…
edit: It is also not an option to modify the COM object in any way.
I found the problem, it wasn’t the cross-thread operation persay. In my GUIForm I created a subwindow and used SetParent() to parent it to the COM server’s app window. This seems to have caused the issues with the COM proxy being disconnected (although a more experience COM expert might have to enlighten me as to why it behaved like this).
Instead of parenting my control to the window I’m going to fully disconnect it and just hook WM_WINDOWPOSCHANGING to move my control with the main App window.