我正在使用以下方法从MongoDB收集数据:
public IEnumerable<TOutput> GetMatchingJobs<TOutput>(JobInfoFilterParameters filterParameters, FetchOptions<JobInfoRecord, TOutput> fetchOptions)
{
var filter = CreateFilterDefinition(filterParameters);
var options = CreateFindOptions(fetchOptions, false);
return MongoDatabaseStorageService.WithRecords<JobInfoRecord, List<TOutput>>
(collection => collection.FindAsync(filter, options).Result.ToListAsync().Result);
}
/// <summary>
/// Performs an operation on the database, automatically disconnecting and retrying
/// if the database connection drops.
/// </summary>
/// <param name="operation"></param>
public TResult WithRecords<T, TResult>(Func<IMongoCollection<T>, TResult> operation)
{
try { }
finally { _lock.EnterUpgradeableReadLock(); }
try
{
return WithRecordsInternal(operation);
}
finally
{
_lock.ExitUpgradeableReadLock();
}
}
private TResult WithRecordsInternal<T, TResult>(Func<IMongoCollection<T>, TResult> operation)
{
try
{
return operation(GetCollection<T>());
}
catch (IOException)
{
// There is an issue in mongo drivers when IOException is thrown instead of reconnection attempt.
// Try repeat operation, it will force mongo to try to reconnect.
return operation(GetCollection<T>());
}
}
我想知道使用FindAsync()
和ToListAsync()
等异步操作与.Result
如何使用async-await
提升性能(或通过并行化数据库访问来提高吞吐量)或正确使用async
正确的模式(如果我打破了它)?
答案 0 :(得分:3)
使用异步IO无法提高数据库访问吞吐量。所有这一切都改变了呼叫启动和完成的方式。完全相同的数据通过网络传输。
您可以通过并行化数据库访问来提高吞吐量,但这与异步IO无关。
collection.FindAsync(filter, options).Result.ToListAsync().Result
在这里,你得到了最糟糕的性能:由于异步导致的呼叫开销增加,然后阻塞,这又是代价高昂的。如果这是个好主意,那么图书馆就会在内部为你做这个模式。
答案 1 :(得分:0)
在某种意义上,您可以并行化数据库调用,但是您需要从上到下使用Async-Await。这是一个做一组异步调用,捕获他们的任务承诺,等待他们全部完成的例子。
var tasks = new List<Task>();
tasks.Add(AsyncCall1);
tasks.Add(AsyncCall2);
await Task.WhenAll(tasks);
当您调用Async方法并使用.Result时,您会立即使调用线程等待异步方法完成。以上只是一个简单的例子来传达你可以并行放置异步操作的观点。一般来说,Async-Await是一种病毒,它往往会在整个代码库中传播,因为最好的优势来自于从上到下一直使用它。只使用.Result的Async实际上并没有以比使用同步调用时更昂贵的方式执行相同的操作。
您要测量的另一个潜在选项是将异步调用添加到任务集合,然后调用:
Task.WhenAll(tasks).Wait();
这会导致调用线程在.Wait上阻塞,但是一旦完成调用线程将继续,集合中的任务将并行处理。我个人更喜欢一直使用Async-Await,但你可能没有这个选择。
此博客系列可能对您有所帮助。 http://blog.stephencleary.com/2012/02/async-and-await.html