Hi,
Frameworks Threading Models
Lets talk about Bluetooth Framework here. But this is correct for any Framework: WiFi, IrDA, Serial.
Internally Bluetooth Framework uses threads for asynchronous operations. By some reasons it also uses separate threads for WinRT operations (not sure if that is applicable for your case but wanted to let you know). Also the system uses threads to call callbacks (this threads called "free" because it can be executed in any context. Bluetooth Framework also uses "free" threads for some operations so any thread in Bluetooth Framework is "free" or by other word - "undefined").
To notify main application thread that usually handle UI Bluetooth Framework uses Windows Messages. This is the only good way for inter threading communication for such cases. There is also something known as APC but this requires some special code support from application so we decided to do not use APC in Bluetooth Framework. To be able to receive such notifications your application must have Message Loop. By default any Windows UI based applications have Message Loop (at least one, but can be more).
From version 7.6.8.0 Bluetooth framework supports APC as well (IrDA from 7.5.3.0; Serial from 7.4.4.0; Timeline from 7.0.3.0 and WiFi from 7.6.9.0). Please refer to ApcSync demo application).
Bluetooth Framework is designed to be thread safe. So any function can be called from any application thread. But you should always be aware that notification will be delivered to the thread that:
1. has Message Loop;
2. called to Open/Connect method (or other method that "initializes" the class except constructor). This described in documentation.
So let say your application from main UI thread called TwclBluetoothManager.Open() method. After that it can call TwclBluetoothRadio.Pair() method from any other applications thread but only main thread receives authentication events.
This is default usage way of Bluetooth Framework.
Sometime you may need to use it in threads. I am not sure why that can be needed (because it is asynchronous and does not block UI) but assume you need it. In this case you have to:
a) Use your own thread that will have message loop;
b) Use TwclThread class that already has message loop.
The TwclThread is recommended way. When you starts the thread based on TwclThread class the OnInitialize() method called (your class must override it). In this method you have to do all initialization such as create TwclBluetoothManager, assign event handlers and call TwclBluetoothManager.Open(). The method must return true if completed with success.
When your application terminates TwclThread the OnTerminate() method called (your class must override it). You should do all finalization here.
TwclThread provides some mechanism to send "Signals" from your applications main thread to this Bluetooth Framework thread. To do so you can define "commands" and call Signal() method. When TwclThread receives such "signal" the OnSignal() method called. Your class must override this method to process signals.
Let say you declare #define DO_PAIR 1
then call Signal(DO_PAIR)
the OnSignal() method will be called in your class with Id = DO_PAIR and you can call Pair() method than.
That is correct way to use Bluetooth Framework in threads. And this thread model is "asynchronous".
The other threading model is "synchronous". That means that all events fires in its own "free" threads that may or may not your applications main thread, may or may not the thread that called method. It may even be a system thread. So the thread context for the event is undefined and "free". This model called "synchronous" because event call is always synchronous with initial event source: system callback, notification, Bluetooth Framework method call etc. You must process the events as fast as possible because some of them may block system threads (as for example pairing notification processing).. And you must always be sure that the event processing synchronized (if needed) with your applications UI or main thread.
This threading model is useful for console applications, for Windows Services, etc. (see console demo).
To switch Bluetooth Framework to "synchronous" threading model call
TwclMessageBroadcaster.SetSyncMethod(skNone);
The SetSyncMethod() is static and must be called as class member. not as instance member.
The call MUST be executed (the threading model MUST be changed) before any other call to Bluetooth Framework. Better this must be the first code line in your application start routine.