TRemotable
обеспечивает управление временем жизни через свойство DataContext
, поэтому среда выполнения SOAP освобождает сам объект. Пока объект контекста данных существует, все, что он выделил, также будет существовать. Если вы хотите претендовать на владение и ответственность за объект, просто очистите его свойство DataContext
. (Это, вероятно, то, что вы захотите сделать в этом случае, потому что ваше сообщение API-события может быть обработано после того, как событие SOAP завершено.)
Проблема в вашем коде в том, что вы передаете динамический массив через опубликованное сообщение. Когда ваша OnTimer
процедура вернется к своему вызывающему, динамический массив, на который ссылается SystemProbeValues
, уменьшит количество ссылок. Если другой поток еще не обработал сообщение (и, вероятно, не обработал), динамический массив может быть уже уничтожен к тому времени, когда он сможет обработать это сообщение.
Самый простой способ - очистить ссылку в обработчике событий таймера, не уменьшая счетчика ссылок, а затем сделать обратное в обработчике сообщений. После публикации сообщения очистите переменную:
LParam(SystemProbeValues) := 0;
В обработчике сообщений очистите старое значение глобальной переменной ProbeValues
и присвойте новое значение следующим образом:
ProbeValues := nil;
LParam(ProbeValues) := Msg.LParam;
Другая проблема, скрывающаяся в вашем коде, может заключаться в использовании TTimer
в потоке, отличном от VCL. Этот класс создает дескриптор окна для совместного использования всеми экземплярами класса. Если ваш поток таймера не является единственным потоком в программе, который использует TTimer
, у вас, вероятно, будут проблемы, либо с функциями, выполняющимися в неправильном потоке, либо с функциями, которые вообще не работают. Вместо TTimer
вы можете использовать SetTimer
для создания таймера ОС вручную или вы можете создать ожидаемый таймер , который может быть более подходящим для использования в потоке, который не нужно реагировать на действия пользователя.