Я думаю, что вам не хватает здесь сборки мусора.
Не проверял ваш код, но это, безусловно, может быть источником проблемы.
var sqlReq:SQLRequest = new SQLRequest(handleResult, _dbConn, sql);
sqlReq.startLoad();
СсылкаsqlReq
является локальным для функции и становится недоступным, когда функция возвращается.Это делает его коллекционным.Я предполагаю, что во время выполнения AIR должен быть какой-то код, который собирает мусор более агрессивно, когда задействованы соединения SQL.Потому что, как правило, вам не удастся сохранить ссылку на ваш объект (по крайней мере, в веб-среде, по моему опыту; это ошибка в таком коде, тем не менее; вам просто нужно быть в плохой день, чтобы испытать)это).
setTimeout
маскирует эту проблему (или почти решает ее, хотя и непреднамеренно), потому что функция setTimeout
использует Timer
внутри.Запуски таймеров не собираются.Таким образом, таймер активен и работает, и имеет ссылку на ваш экземпляр SQLRequest
, что делает его пригодным для повторного использования и, следовательно, недоступным для сбора.Если ваш вызов БД занимает больше времени, чем тайм-аут, вы вернулись в той же ситуации.
Чтобы решить эту проблему, сохраните ссылку на объект и утилизируйте ее, когда закончите.
Редактировать
Другой вариант, если вы не хотите изменять способ работы кода, - сохранить ссылку на экземпляр в словаре с классовой областью (т. Е. Статическом).на время разговора (этот словарь не должен использовать слабые ссылочные ключи по понятным причинам).
Вы добавляете скрытый побочный эффект к своему методу, который не является признаком хорошего дизайна в целом, но до тех пор, пока вы удаляете его, когда завершен вызов в БД (независимо от того, был он успешным или нет)Вы в безопасности, поэтому я думаю, что проблема скорее в стиле, чем в чем-либо еще.
Я имею в виду что-то вроде этого:
private static var _dict:Dictionary = new Dictionary();
public function startLoad():void
{//execute
_statement.execute();
// add a self reference to dict so the instance won't be collected
// do this in the last line, so if we have an exception in execute, this
// code will not run (or add a try/catch if you want, but this is simpler
// and cleaner, IMO
addToDict();
}//execute
private function handleResult(e:SQLEvent):void
{//handleResult
// remove the self reference before running any other code
// (again, this is in case the code that follows throws)
removeFromDict();
trace("Good SQL Request");
_callback(e);
dispatchEvent(e);
}//handleResult
private function handleError(e:SQLErrorEvent):void
{//handleError
// same comment as handleResult
removeFromDict();
trace("SQL Error: " + e.errorID + ": " + e.error);
//dispatchEvent(e);
}//handleError
private function addToDict():void {
_dict[this] = true;
}
private function removeFromDict():void {
if(_dict[this]) {
delete _dict[this];
}
}