I instantiate a service class that contains a COM interop component that does terminal automation. I am using Task Library (TPL) from Microsoft. I want to make calls to the COM object from a TPL task (background thread) so my UI doesn't freezes while the COM object is working.
However when I call my first function from the background thread (which receives an IntPtr) an COM Exception is thrown detailing HRESULT: 0xC0000005.
I know this is an access violation exception and I think I'm not mashaling my object the right way.
How can I call methods from a COM object created in the main thread from a background thread?
public void Button1_Click(object sender, EventArgs e)
{
var comWrapper = new COMWrapper(); // A simple wrapper for a COM object
Task.Factory
.StartNew(() => LoadStuff(comWrapper))
.ContinueWith(() => {
// Output results...
});
}
int LoadStuff(COMWrapper w)
{
return w.LoadStuffFromCOM();
}
Method that calls the COM object:
int LoadStuffFromCOM()
{
string buffer;
IntPtr pointer = Marshal.StringToHGlobalUni(buffer);
return comObject.GetValue(pointer); // Exception here...
}
It is possible to have COM / OLE Interop objects running on background, but they must be compiled with correct Threading Model
In case of Delphi for MTA it should be compiled
initialization
TTypedComObjectFactory.Create(ComServer, TSomeLogic, Class_SomeLogic,
ciMultiInstance, tmFree);
end.
In case of STA by default it uses
initialization
TTypedComObjectFactory.Create(ComServer, TSomeLogic, Class_SomeLogic,
ciMultiInstance, tmApartment);
end.
It should be simmilar in C/C++ and other unmanaged languages
More information can be found here: http://msdn.microsoft.com/en-us/library/ff647812.aspx#scalenetchapt07 _topic11