我是否应该在以下案例实例中使我的SQL查询异步?

时间:2016-08-07 09:25:24

标签: c# sql-server database asynchronous

总结一下我的问题:我必须对3个不同的端点进行3次单独调用。我必须通过大量记录以编程方式执行此操作。其中两个调用是使用异步HTTP请求到两个不同的,我使用aysnc await。我要做的第三个调用是对没有API包装器的MS SQL数据库的查询。对API的两次调用每次需要大约22秒,对数据库的查询需要大约2秒。单独这是好的,但是当我将MS SQL查询作为方法链的一部分时,整个事物变得同步。我最初会将用户大量时间用于同时查询两个API,我的应用程序将在尝试下次调用数据库之前等待这些查询完成。

我之前被告知数据库查询是事务性的,不能异步。我想知道这是否属实,我实际上可以对数据库进行真正的异步调用。

我的另一个选择是在执行作业时预先填充我可以从一系列SQL查询创建的List<T>个对象到数据库。但是我担心的是这个列表中存储的对象的潜在数量,是否存在需要处理数十万条记录的某些作业的内存过载的危险,或者可能是搜索对象的速度是否正确值。

1 个答案:

答案 0 :(得分:6)

  

当我将MS SQL查询作为方法链的一部分时,整个事物变得同步。

这是一个不正确的实现。您当然可以在单个函数中混合同步和异步调用。

假设您有以下三种方法:

async Task<Result1> FirstQueryAsync() {
    ...
}
async Task<Result2> SecondQueryAsync() {
    ...
}
Result3 QueryDb() {
}

你可以这样写:

async Task<OverallResult> QueryThreeSources() {
    // Fire off async queries
    var firstTask = FirstQueryAsync().ConfigureAwait(false);
    var secondTask = SecondQueryAsync().ConfigureAwait(false);
    // Do synchronous query
    var third = QueryDb();
    // Await the results of the other two
    var first = await firstTask;
    var second = await secondTask;
    return Combine(first, second, third);
}
  

我之前被告知数据库查询是事务性的,不能异步。

这是不正确的。查询的事务性质在RDBMS内部显示在RDBMS端。这完全独立于程序同步或异步接收数据的决定。 .NET提供了用于访问SQL Server的异步API,因此您绝对可以使用异步样式重写数据库代码。

  

我的另一个选择是在执行作业时预先填充我可以从一系列SQL查询创建的List<T>个对象到数据库。

只有在多次查询相同数据时,列表选项才会有效。如果您的所有查询都倾向于带来不同的数据子集,这些子集与您查询的表中存储的整体数据相比较小,则缓存List<T>中的数据通常会适得其反。