1

我最近遇到了这个非常奇怪的问题。最初我有这段代码

public async Task<string> Fetch(string module, string input)
{
    if (module != this._moduleName)
    {
        return null;
    }
    try
    {
        var db = new SQLiteAsyncConnection(_dbPath);
        ResponsePage storedResponse = new ResponsePage();

        Action<SQLiteConnection> trans = connect =>
            {
                storedResponse = connect.Get<ResponsePage>(input);
            };
        await db.RunInTransactionAsync(trans);
        string storedResponseString = storedResponse.Response;
        return storedResponseString;
    }
    catch (Exception e)
    {
        return null;
    }
}

但是,事务完成运行后,控制权将永远不会交还给我的代码。我跟踪了程序,似乎在锁被释放后,程序流停止了。然后我切换到使用 SQLiteAsyncConnection 类中的 GetAsync 方法。基本上它做了同样的事情,所以我仍然在等待时被阻止。然后我删除了异步调用并使用了如下的同步 api:

public async Task<string> Fetch(string module, string input)
{
    if (module != this._moduleName)
    {
        return null;
    }
    try
    {
        var db = new SQLiteConnection(_dbPath);
        ResponsePage storedResponse = new ResponsePage();
        lock (_dbLock)
        {
            storedResponse = db.Get<ResponsePage>(input);
        }
        string storedResponseString = storedResponse.Response;
        return storedResponseString;
    }
    catch (Exception e)
    {
        return null;
    }
}

只有这样,逻辑才能流回我的代码。但是我不知道为什么会这样。另一个问题是,对于这种简单的查询,如果我使用aysnc api而不是sync api,在查询时间方面有什么好处吗?如果没有,我会坚持使用同步版本。

4

1 回答 1

2

您很可能从 调用Result(或Wait)进一步向上调用堆栈Fetch正如我在我的博客最近的 MSDN 文章中解释的那样,这将导致死锁。

对于您的第二个问题,有一些开销async,因此对于极快的异步操作,同步版本会更快。除非您进行分析,否则无法判断您的代码是否属于这种情况。

于 2013-05-30T20:14:22.513 回答