QuickOPC User's Guide and Reference
Callback Queuing
Development Models > Imperative Programming Model > Callback Queuing

All callbacks (including event notifications) originating from any of the EasyXXClient or EasyXXSubscriber objects are (by default) sent in a queued manner by a dedicated internal thread, improving resiliency against errors in custom code, and decreasing the possibility of deadlocks. When there is a sudden peak in the rate of incoming events, they can accumulate temporarily in the queue, allowing the processing to proceed smoothly.

This callback queuing can be turned on or off by the QueueCallbacks property. Turning off the callback queuing is only advisable in very special circumstances. When the callback queuing is turned off, the callback and event handling is subject to much stricter rules with regard to performance, but also with regard to what the handlers are allowed to do. Most importantly, the handlers must not call any methods on the originating component, because doing so can cause deadlocks. This rule also applies to calls that may be inflicted by the SynchronizationContext on the component. For example, the common synchronization contexts based on Windows messages (for Windows Forms and WPF) can call other "posted" methods before the action that are instructed to do, causing unpredictable behavior and a possible deadlock too.

For the reasons described above, do not turn the callback queuing off unless you know very well what you are doing.

The capacity of the callback queue is given by the CallbackQueueCapacity property. The memory is not preallocated for the full maximum size, however, and therefore under normal circumstances, there is no penalty for using quite high queue capacities. The callback queue capacity should be large enough to be able to hold all incoming callbacks in case of a sudden "burst", before they are all processed (consumed) by your code.

For errors coming from subscriptions, QuickOPC uses the same "channel" as for success notifications. For example, in case of the EasyUAClient Class, this means that the errors come through the DataChangeNotification Event or EventNotification Event, and the component treats each monitored item separately. Consequently, in case of an error that affects the whole connection to a particular server (or more servers), callbacks (and/or events) will be generated for every monitored item affected. This is by design. If you are subscribed to larger number of monitored items, this itself can create a "burst" that is way above the normal rate of events. Your code, and the size of the callback queue, need to be prepared for this scenario as well.

If the amount of notifications that needs to be held in the queue exceeds its capacity, a callback queue overflow occurs, and these notifications are lost. In addition, a LogEntry Event is generated on the EasyXXClient or EasyXXSubscriber, with corresponding message. If a notification is removed from a queue while it has overflown, the overflow status is cleared, and a different  LogEntry Event is generated on the component ("overflow clearing"). The event contains overflow count, which is effectively the number of notifications that have been lost due to the queue overflow.

The idle time before the internal thread executing the queued callbacks is stopped is controlled by the CallbackQueueIdleTimeToSleep property. The thread is stopped as an optimization measure, to reduce the amount of system resources consumed. When new callbacks come, the thread is automatically started.

See Also