总结一下我的问题:我必须对3个不同的端点进行3次单独调用。我必须通过大量记录以编程方式执行此操作。其中两个调用是使用异步HTTP请求到两个不同的,我使用aysnc await。我要做的第三个调用是对没有API包装器的MS SQL数据库的查询。对API的两次调用每次需要大约22秒,对数据库的查询需要大约2秒。单独这是好的,但是当我将MS SQL查询作为方法链的一部分时,整个事物变得同步。我最初会将用户大量时间用于同时查询两个API,我的应用程序将在尝试下次调用数据库之前等待这些查询完成。
我之前被告知数据库查询是事务性的,不能异步。我想知道这是否属实,我实际上可以对数据库进行真正的异步调用。
我的另一个选择是在执行作业时预先填充我可以从一系列SQL查询创建的List<T>
个对象到数据库。但是我担心的是这个列表中存储的对象的潜在数量,是否存在需要处理数十万条记录的某些作业的内存过载的危险,或者可能是搜索对象的速度是否正确值。
答案 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>
中的数据通常会适得其反。