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?

Assignee Loading
Time tracking Loading