Neurosdk and single-threaded apartment
Hi,
We are working on C# Windows Forms application that acquires data from Brainbit device.
As it's recommended for WinForms applications, we set single-threaded apartment for the application main thread:
[STAThread]
public static void Main(string[] args)
But when we try to create DeviceEnumerator, we get exception in neurosdk-x86d.dll:
SEHException: External component has thrown an exception.
at Neuro.DeviceEnumerator.create_device_enumerator(DeviceType type)
at Neuro.DeviceEnumerator..ctor(DeviceType deviceType) in D:\Projects\sdk\neuro-sdk\wrappers\windows\neurosdk\DeviceEnumerator.cs:line 33
...
The exception is not thrown if we decorate the application entry point with [MTAThread] attribute (or omit the apartment attribute at all).
The following simple code reproduces the issue:
[STAThread]
public static void Main(string[] args)
{
create_device_enumerator(DeviceType.Brainbit);
}
[DllImport("neurosdk-x86.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr create_device_enumerator(DeviceType type);
It seems that the cause of the problem is the call to winrt::init_apartment(), that tries to set multithreaded apartment for the current thread
neuro-sdk\core\ble\win\windows_ble_enumerator.cpp:
WindowsBleEnumerator make_ble_enumerator(const std::vector<std::string> &uuid_filters) {
winrt::init_apartment();
return WindowsBleEnumerator(uuid_filters);
}
For now we've workarounded the issue by creating DeviceEnumerator in separate MTA thread like this:
private static DeviceEnumerator CreateDeviceEnumerator()
{
DeviceEnumerator deviceEnumerator = null;
Thread mtaThread = new Thread(() => {
deviceEnumerator = new DeviceEnumerator(DeviceType.Brainbit);
});
mtaThread.SetApartmentState(ApartmentState.MTA);
mtaThread.Start();
mtaThread.Join();
return deviceEnumerator;
}
Unfortunately, we are not sure that this is a safe way to solve the problem.
How can we use neurosdk in STA application?