异步方法没有可用的扩展方法,但结果变量确实有

时间:2017-07-04 12:24:26

标签: c# mongodb asynchronous

我使用带有c#和异步方法的MongoDB在标准存储库类中创建了一些方法,并且我偶然发现了一些奇怪的行为。

最后它可能并不奇怪,而问题在于我自己对异步编程缺乏经验。

考虑以下代码:

public async Task<T> GetItem<T>(ObjectId id) where T : BaseItemEntity
        {
            var col = GetTypedCollection<T>();

            var model = await col.FindAsync(x => x.Id == id);

            return await model.FirstOrDefaultAsync();
        }

现在完全没问题,没有编译错误,但实际上我不确定它的正确呼叫等待2次。

现在考虑以下代码:

public async Task<T> GetItem<T>(ObjectId id) where T : BaseItemEntity
        {
            var col = GetTypedCollection<T>();

            var model = await col.FindAsync(x => x.Id == id).FirstOrDefaultAsync();

            return model;
        }
根据编译器,这是非法的。它抱怨FirstOrDefaultAsync()不是一种可用的调用方法。我必须首先调用.Result来访问.FirstOrDefaultAsync()。

这里发生了什么?

2 个答案:

答案 0 :(得分:3)

var model = await col.FindAsync(x => x.Id == id).FirstOrDefaultAsync();

应该是:

var model = await (await col.FindAsync(x => x.Id == id)).FirstOrDefaultAsync();

这是因为FindAsync返回一个Task对象,FirstOrDefaultAsync不适用于该对象。等待操作产生实际结果。

这是async / await IMO最烦人的事情之一,因为它需要括号或变量来保存等待结果以便进一步处理。

答案 1 :(得分:1)

我认为它实际应该是

var model = await (await col.FindAsync(x => x.Id == id)).FirstOrDefaultAsync();

两个Async方法都返回一个Task对象,而Tasks没有FirstOrDefault()方法(这就是为什么需要await in())。另一个是需要的,因为这种方式模型是你的对象而不是任务。