Author Topic: Asynchronous messaging  (Read 23534 times)

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Asynchronous messaging
« on: June 24, 2018, 10:16:39 PM »
Asynchronous messaging

By default Wireless Communication Library(Bluetooth, IrDA, Serial and WiFi Frameworks) (WCL) uses Windows messages for inter-threading synchronization. Such synchronization requires that your application has message loop. It is good for WinForms (or other classic desktop) applications because all WCL events are always synchronized with the main application thread. But such synchronization may cause a problem in console or service applications.

WCL already includes one solution: wclThread class. The class allows to move all work with WCL into separate thread that implements message loop for default inter-threading synchronization. However it brings more complex coding for your applications.

The new Asynchronous Message subsystem does not require message loop and WCL can be used in console or service (or in threads) without any special coding. However with such synchronization method the WCL events may be called (fired) from any thread (not from only main applications thread). We call it "free threads" because there is no warranty which thread is used to fire an event.

Offline MrPaulCarpenter

  • Newbie
  • *
  • Posts: 12
  • Karma: 0
wclThread
« Reply #1 on: October 23, 2018, 07:10:17 PM »
I have an application that I want to use to connect to multiple Bluetooth devices at the same time.  For that reason it is threaded, using .Net / C# Tasks.  It appears that I am losing data when I/O goes from one task to another.  I am not sure if the loss happens at BtClient.Write() for from OnData() being referenced in a different thread. 

Your comment says that wclThread is available for those who need it, but I don't see any examples of the right way to use the class. I am a assuming:
1) Create the  wclRfCommClient here
2) respond to OnData here
3) Funnel write requests through this.

Any advise is appreciated

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Re: Asynchronous messaging
« Reply #2 on: October 24, 2018, 03:13:45 AM »
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.
« Last Edit: June 04, 2019, 04:24:52 PM by Mike Petrichenko »

Offline Mike Petrichenko

  • Bluetooth Framework Developer
  • Administrator
  • Hero Member
  • *****
  • Posts: 3675
  • Karma: 1000
    • Wireless Communication Libraries
Re: Asynchronous messaging
« Reply #3 on: October 24, 2018, 11:57:49 AM »
So now back you your question.

First, Bluetooth Framework is asynchronous so you do not need any threads there because it does not block UI. The best solution.

Second, in case you need threads there are 2 ways (as described in previous post about Frameworks threading models):

1. Use wclThread class.
2. Use "synchronous" threading model.

The "synchronous" threading model is good for service or console applications (plese, refer to console demo or to any of IoT demos).

For common UI based applications wclThread is better. It is easy in use actually.

 

Sitemap 1 2 3 4 5 6 7