I am working an SDK for a DSLR camera which has the following instructions:
Notes on Developing Windows Applications When creating applications that run under Windows, a COM initialization is required for each thread in order to access a camera from a thread other than the main thread. To create a user thread and access the camera from that thread, be sure to execute CoInitializeEx( NULL, COINIT_APARTMENTTHREADED ) at the start of the thread and CoUnInitialize() at the end. Sample code is shown below. This is the same when controlling EdsVolumeRef or EdsDirectoryItemRef objects from another thread, not just with EdsCameraRef.
void TakePicture(EdsCameraRef camera)
{
// Executed by another thread
HANDLE hThread = (HANDLE)_beginthread(threadProc, 0, camera);
// Block until finished
::WaitForSingleObject( hThread, INFINITE );
}
void threadProc(void* lParam)
{
EdsCameraRef camera = (EdsCameraRef)lParam;
CoInitializeEx( NULL, COINIT_APARTMENTTHREADED );
EdsSendCommand(camera, kEdsCameraCommand_TakePicture, 0);
CoUninitialize();
_endthread();
}
My application is a C# WinForms app and normally, I use the managed thread class and Control.Invoke functions to avoid cross-thread issues.
Since I do not have sample source code in C# for consuming the SDK, my question is, is it useful and/or necessary to use CoInitializeEx
in an app marked with the [STAThread]
attribute?
I have not come across a scenario were I would need to have my app create a new apartment for threads so some insight would be helpful to understand threading models better.
UPDATE: After reading some more about apartments and COM, it is beginning to make some sense. Now I'm wondering what the .NET managed thread class defaults to and can we specify an apartment model in a managed way to each thread without P/Invoke?