Разница между Find и FindAsync
Я пишу очень простой запрос, который просто получает документ из коллекции в соответствии с его уникальным идентификатором. После некоторой фрустрации (я новичок в монго и модели программирования async/await), я понял это:
IMongoCollection<TModel> collection = // ...
FindOptions<TModel> options = new FindOptions<TModel> { Limit = 1 };
IAsyncCursor<TModel> task = await collection.FindAsync(x => x.Id.Equals(id), options);
List<TModel> list = await task.ToListAsync();
TModel result = list.FirstOrDefault();
return result;
Это работает, отлично! Но я продолжаю видеть ссылки на метод "Найти", и я это продумал:
IMongoCollection<TModel> collection = // ...
IFindFluent<TModel, TModel> findFluent = collection.Find(x => x.Id == id);
findFluent = findFluent.Limit(1);
TModel result = await findFluent.FirstOrDefaultAsync();
return result;
Как оказалось, это тоже работает, отлично!
Я уверен, что есть важная причина, по которой у нас есть два разных способа достижения этих результатов. В чем разница между этими методологиями и почему я должен выбирать один из них?
Ответы
Ответ 1
Разница заключается в синтаксисе.
Find
и FindAsync
оба позволяют создавать асинхронный запрос с одинаковой производительностью, только
FindAsync
возвращает курсор, который не загружает сразу все документы и предоставляет вам интерфейс для получения документов по одному из курсора DB. Это полезно в случае, если результат запроса огромен.
Find
предоставляет вам более простой синтаксис с помощью метода ToListAsync
, где он извлекает документы из курсора, а возвращает все документы сразу.
Ответ 2
Представьте, что вы выполняете этот код в веб-запросе, при вызове метода поиска поток запроса будет заморожен до тех пор, пока возврат базы данных не приведет к вызову синхронизации, если это длинная операция с базой данных, для которой требуется несколько секунд, вы будете есть один из потоков, доступных для обслуживания веб-запроса, ничего не предпринимающего, просто ожидая, что база данных вернет результаты и потеряет ценные ресурсы (количество потоков в пуле потоков ограничено).
С помощью FindAsync поток вашего веб-запроса будет бесплатным, пока ожидает базы данных для возврата результатов, это означает, что во время обращения к базе данных этот поток может посещать другой веб-запрос. Когда база данных возвращает результат, код продолжает выполнение.
Для длительных операций, таких как чтение/запись из файловой системы, операции с базами данных, общение с другими службами, рекомендуется использовать асинхронные вызовы. Поскольку пока вы ожидаете результатов, потоки доступны для обслуживания другого веб-запроса. Это более масштабируемо.
Взгляните на эту статью Microsoft https://msdn.microsoft.com/en-us/magazine/dn802603.aspx.