Reputation: 4381
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...
}
Upvotes: 0
Views: 1592
Reputation: 6694
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
Upvotes: 0
Reputation: 2062
IF you are desperate you could spawn a whole separate process which executed the com code. Then you would only have to write the ipc
Upvotes: 0
Reputation: 161781
Many legacy COM objects were made to run inside of a desktop application. That means they expected to run on the UI thread, with the Windows message pump as the only synchronizing method.
You're now trying to run that code in an environment it may never have "heard of". There's a good chance that you have violated the assumptions the author made when he wrote the code.
The code may work if you don't violate the assumptions, but if you do, then you're going to have a problem (or two, or two dozen).
Upvotes: 1