1

这是我在此的头一篇博文。我之所以问,是因为我没有线索,也找不到有关此特定问题的任何信息。

我的问题是:在 Adob​​e AIR 中,有没有办法进行同步 usleep() 等效(延迟执行 200 毫秒),或者有没有办法在某处指定 SQLite 繁忙超时?

我有一个 AIR 应用程序,它以同步模式使用数据库,因为代码无法处理 SQL 查询中的事件/回调需求。

有时从另一个应用程序访问数据库,因此它很忙。因此,语句的 execute() 会抛出 SQLerror 3119 detail 2206。在这种情况下,应在短暂延迟后重试该命令。

由于计算机上正在运行另一个应用程序,因此我想尽量避免忙于等待,但是由于三件事,我一直坚持使用它:

首先,我无法找到一种方法给 SQLConnection 一个繁忙的超时值,就像在 C 中可以使用函数 sqlite3_busy_timeout()

其次,我无法在 Adob​​e 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 负载,因为该应用程序应在使用电池时在笔记本电脑上运行。

谢谢。

-蒂诺

4

0 回答 0