C#中正确使用Mongo的Find().ToList()异步方法的相关疑问
问题解答
1. 现有写法的异步性说明
你当前的写法不存在阻塞问题,全程都是异步执行的。
MongoDB C#驱动中,同步的Find()方法仅在本地内存中组装查询条件、生成查询定义对象,不涉及任何网络IO或者数据库调用,本身是非常轻量的纯计算操作,不会产生阻塞。真正触发数据库请求的是后续的ToListAsync()方法,这个方法是标准的异步IO实现,会立刻返回Task对象,后续执行过程不会阻塞调用线程。
2. 是否需要替换为FindAsync
绝大多数场景下不需要替换。FindAsync一般用于需要手动控制游标遍历、分批拉取数据的场景,如果你的需求就是直接拉取全量结果转为List,原本的Find()+ToListAsync()写法不仅逻辑更简洁,性能上也没有任何损失。
3. 不用异步状态机调用FindAsync的实现方式
如果你确实有使用FindAsync的需求,又不想给方法加async关键字生成异步状态机,可以通过ContinueWith加Unwrap的方式链式处理返回的Task,示例代码如下:
public Task<List<Item>> GetItemsByColor(string color) { return collection.FindAsync(x => x.Color == color) .ContinueWith( task => task.Result.ToListAsync(), TaskContinuationOptions.OnlyOnRanToCompletion ) .Unwrap(); }
注意这个写法可以保证上游FindAsync产生的异常正常传递到外层Task,如果你需要额外处理异常,补充对应的TaskContinuationOptions配置即可。
内容的提问来源于stack exchange,提问作者Stijn
相关产品推荐
相关产品推荐

