Queued Message Handler

From LabVIEW Wiki
Jump to: navigation, search

The Queued Message Handler (QMH) design pattern is a combination of producer/consumer, and event handler architectures together.  The producer loop, called the Event Handler Loop (EHL), contains an event structure that sends messages to the consumer loop, called the Message Handler Loop (MHL). The MHL receives and processes the messages. A message is enqueued when a UI event is triggered. The QMH can also be designed to provide feedback from the consumer to the producer using User Events.[1]

Queued Message Handler (QMH) with one Event Handler Loop (EHL) and one Message Handler Loop (MHL)

Parts of a QMH

Event Handler Loop (EHL)

The EHL's main purpose is to react to events triggered by the user through interactions with the front panel controls. However, events could come from other sources through the use of user events. When an event is fired or generated, the diagram of the event structure corresponding to that event will execute. The corresponding message is then created and enqueued to be sent to the MHL.

Message Handler Loop (MHL)

The MHL's main purpose is to execute on the incoming messages. The MHL waits until there is a message on the queue and dequeues it. With the message structure shown above, the message is unbundled to see what the message name, or command, is. A case structure then executes the diagram corresponding to the message. In the diagram, the data is converted from the variant and used in the execution of the case.

Messages (EHL to MHL)

Messages can be structured in many ways but usually consists of two parts:

  1. Message name or Command - name given to the message to differentiate it from other messages and must be unique.
  2. Data - payload of data used by the message to execute the desired function.

The Command can be any unique type. Often it is a string or an enumeration. In the case of the string

User Events (MHL to EHL)

User events are the communication in the opposite direction, from the MHL back to the EHL. They can have any data type or structure, see User events for more details.

Stop Conditions

Remember that there are now two, or more, parallel loops running. If one is stopped without the other, the program will become unresponsive. Therefore, the stop condition in any loop should ensure the other loop(s) will stop too.

  • If the stop is initiated in the EHL, send a message to command the MHL(s) to stop.
  • If the stop is initiated in the MHL, send a stop user event to the EHL to stop. If there are other MHL, have the EHL send messages for them to stop too.

Best Practices

  • Do not put long executing code in the EHL. If code in the event takes a long time to run, this locks up the UI and makes it seem to the user that the program has become unresponsive.
  • If having more than one MHL, use a separate queue for each one. If you use only one queue for more than one MHL, only the first MHL to dequeue the message would get it and there is no guarantee which MHL would get it. Queues are a "Many-to-One" data communication mechanism; meaning, there can be many enqueuers but should be only one dequeuer.
  • If using a string as the data type for your Commands, you must handle a default case in the MHL. The default case will run if a Command is misspelled, so consider throwing an error or displaying a popup in the default case for unrecognized Commands. You can avoid this problem by using an enumeration instead.
  • If using an enumeration (enum) as the data type for your Commands, make it a TypeDef, or Type Definition. This is so when the enum has changed, all constants and controls of the enum will be updated. Also, you could have a default case just like when having a string Command. However, as long as all entries in the enum are handled a default case is not required. When an enum is updated with a new entry, a benefit of not having a default case is that the VI will become broken. This alerts you that the new enum entry is not handled and lets you decide how to handle it rather than having it automatically trigger the default case.

Use Cases

External Links

References

  1. "Queued Message Handler Template" by National Instruments (http://www.ni.com/tutorial/53391/en/)