这是我在此的头一篇博文。我之所以问,是因为我没有线索,也找不到有关此特定问题的任何信息。
我的问题是:在 Adobe AIR 中,有没有办法进行同步 usleep() 等效(延迟执行 200 毫秒),或者有没有办法在某处指定 SQLite 繁忙超时?
我有一个 AIR 应用程序,它以同步模式使用数据库,因为代码无法处理 SQL 查询中的事件/回调需求。
有时从另一个应用程序访问数据库,因此它很忙。因此,语句的 execute() 会抛出 SQLerror 3119 detail 2206。在这种情况下,应在短暂延迟后重试该命令。
由于计算机上正在运行另一个应用程序,因此我想尽量避免忙于等待,但是由于三件事,我一直坚持使用它:
首先,我无法找到一种方法给 SQLConnection 一个繁忙的超时值,就像在 C 中可以使用函数 sqlite3_busy_timeout()
其次,我无法在 Adobe AIR / Actionscript 中找到与 C usleep() 命令等效的命令。
第三,我无法在这个位置使用事件/计时器/回调等。SQL execute() 必须是同步的,因为它是从应用程序中无数地方的深层嵌套类和函数调用的。
如果应用程序可以在执行 SQL 时处理事件/回调,那么无论如何我都会使用异步数据库,所以这个问题不能使用事件来解决。重试必须在最低级别完成,而不使用 AIR 事件处理工具。
最低级别的代码如下所示:
private static function retried(fn:Function):void {
var loops:int = 0;
for (;;) {
try {
fn();
if (loops)
trace("database available again, "+loops+" loops");
return;
} catch (e:Error) {
if (e is SQLError && e.errorID==3119) {
if (!loops)
trace("database locked, retrying");
loops++;
// Braindead AIR does not provide a synchronous sleep
// so we busy loop here
continue;
}
trace(e.getStackTrace());
trace(e);
throw e;
}
}
}
此函数的一个示例用法是:
protected static function begin(conn:SQLConnection):void {
retried(function():void{
conn.begin(SQLTransactionLockType.EXCLUSIVE);
});
}
此代码的输出类似于:
database locked, retrying
database available again, 5100 loops
阅读:应用程序每秒循环超过 500 次。我想以某种方式将其减少到 5 个循环以减少等待时的 CPU 负载,因为该应用程序应在使用电池时在笔记本电脑上运行。
谢谢。
-蒂诺