Асинхронное программирование

Библиотека LinAPI позволяет реализовывать в приложениях асинхронное выполнение запросов и обработку ответов. Выполнение функции называют асинхронным, если программа продолжает работу, не дожидаясь завершения выполнения функции. Программист может определить свою функцию обработки ответа. В данном случае, когда выполнение функции завершится, работа программы будет прервана, и произойдёт вызов функции обработки ответа, которая может произвести какие-либо действия. Асинхронная работа бывает удобна в тех случаях, когда приложение, кроме работы с БД, ведёт другие активные действия (например, прорисовку изображений или чтение данных с устройств внешней памяти), или приложение посылает к серверу БД несколько вспомогательных запросов, никак не связанных между собой (или наоборот, ответы от которых должны быть обработаны одновременно), или приложение посылает запрос, про который заранее известно, что он будет выполняться долго, а тем временем можно делать что-то другое и т.п. В дистрибутивной поставке СУБД ЛИНТЕР есть пример асинхронного загрузчика данных.

Написание асинхронных программ требует особенно тщательного проектирования приложения, так как последовательное выполнение программы может быть нарушено. Все функции библиотеки LinAPI реентерабельны, и асинхронное выполнение не может привести к порче данных. О реентерабельности своих функций обработки ответа программист должен заботиться сам, т.к. нет гарантий, что при выполнении такой функции не может быть вызвана другая (или та же) функция обработки ответа, работающая с теми же данными. Это похоже на многопоточное программирование, и не реентерабельная функция обработки ответа может привести к неконтролируемому поведению приложения, а в худшем случае к его аварийному завершению.

При асинхронной работе некорректные действия приложения могут привести к ситуации, когда происходит потеря адреса пользовательской функции обработки ответа, и она не будет вызвана. Во избежание подобных ситуаций, если ответ на запрос не приходит слишком долго, имеет смысл предусмотреть вызов функции LINTER_ConnectComplete/LINTER_CursorComplete в режиме ожидания ответа.

Если LINTER_ConnectComplete/LINTER_CursorComplete флаг IsComplete выставит равным нулю, следовательно, ответ пришёл, но по каким-то причинам не был обработан. Это значит, что приложение произвело некорректную операцию и должно быть завершено.

Существует приём программирования с использованием асинхронных функций, когда создаётся неявный цикл асинхронных вызовов. Если в теле функции обработки ответа есть асинхронный вызов функции LinAPI с указанием той же функции обработки ответа, то произойдет зацикливание в кольцо асинхронных вызовов. То есть самый первый асинхронный вызов функции LinAPI создаст как бы подпроцесс (поток), который будет прерывать выполнение основной программы только на время выполнения функции обработки ответа. Функция обработки ответа должна быть написана так, чтобы асинхронный вызов стал последним, и после него следовал выход из функции обработки ответа. В противном случае может возникнуть ситуация, когда функция обработки ответа ещё не завершена, а уже пришёл второй ответ и т.д., что приведёт к переполнению очереди асинхронных запросов.

Примечание

Из функции обработки ответа можно производить только асинхронный вызов функции LinAPI. Синхронный вызов делать нельзя, это приведёт к конфликту и зависанию приложения.