c#mongodb在FindAsync扩展中可能出现死锁

时间:2016-04-28 08:52:18

标签: c# multithreading mongodb mongodb-query deadlock

我试图删除代码即时写作。 在我们需要编写的每个FindAsync中都有这段代码:

using (var cursor = await SomeCollection.FindAsync(filter, options))
{
     while (await cursor.MoveNextAsync())
     {
          var batch = cursor.Current;
          foreach (var item in batch)
          {
              //do something
          }
     }
}

我想出了一个延伸。我的代码:

public static async Task<List<T>> GetResultsFromFindAsync<T>(this Task<IAsyncCursor<T>> find)
{
    List<T> result = new List<T>();
    using (var cursor = await find)
    {
        while (await cursor.MoveNextAsync())
        {
            var batch = cursor.Current;
            foreach (var item in batch)
            {
                result.Add(item);
            }
        }
    }

    return result;
}

现在,我只使用:

List<MyObject> lst = await SomeCollection.FindAsync(filter, options).GetResultsFromFindAsync();

问题是:它是否会导致死锁,因为在具有单个Await caluse的进程中涉及2个异步任务。 我知道这个过程确实包含2个Await calus,但是,它们不会相互冲突,或者可能导致数据丢失?

我使用此扩展程序执行了FindAsync并获取了我的数据,因此它的工作正常,但如果可能发生,测试不会100%发生死锁。

我非常想知道原因或原因。 感谢。

2 个答案:

答案 0 :(得分:2)

这会导致死锁吗?是的,但不是因为你列出的原因。

如果有人决定同步调用您的方法并在返回的Wait上使用ResultTask,则他们可能会死锁。因为这个确切的原因,所以充满了“为什么我的任务永远不会完成”的问题。在ConfigureAwait(false)内等待的所有Task上使用GetResultsFromFindAsync来保护自己。

话虽如此,如果GetResultsFromFindAsync总是异步消耗,则没有问题。

关于只有“单await条款” - 实际上并非如此。您在await实施中Task FindAsync返回GetResultsFromFindAsync,从而传播其完成和例外(如果有)。当你打电话

SomeCollection.FindAsync(filter, options).GetResultsFromFindAsync()

,您实际上正在等待Tasks(外部Task等待内部Task)。如果FindAsync恰好抛出(异步),Task返回的GetResultsFromFindAsync将自动转换为Faulted状态,并且当外部{{1}时将重新抛出异常等待。

总之,你所编写的方法在技术上没有任何错误,尽管引入Task不会受到伤害。

修改

说完上述所有内容之后,我个人会考虑将两个调用合并为一个,因此调用ConfigureAwait(false)FindAsync的责任。这是为了防止消费者重用GetResultsFromFindAsync返回的游标,因为我预计以下内容将失败:

FindAsync

答案 1 :(得分:1)

The .NET driver already offers extension methods for this type of thing. ToList, ToListAsync, and ForEachAsync are all available.

http://mongodb.github.io/mongo-csharp-driver/2.2/reference/driver/crud/reading/#iteration