Как я могу выполнять запросы NHibenate асинхронно? - PullRequest
20 голосов
/ 21 марта 2010

Одним из способов повышения масштабируемости серверного приложения является асинхронное выполнение операции ввода-вывода (чтение файлов, сокетов, веб-запросов, запросов к базе данных и т. Д.) Это не означает запуск их в ThreadPool, который будет просто блокировать потоки во время выполнения операции. Правильный способ - использовать асинхронный API (BeginRead, BeginGetResponse, BeginExecuteReader и т. Д.). Проблема хорошо описана в CLR vi C # book.

Вот статья об асинхронных запросах в Linq to SQL .

Есть ли способы выполнить запрос Nhibernate асинхронно? А как насчет Linq для NHibernate?

Спасибо, Андрей

Ответы [ 5 ]

12 голосов
/ 05 сентября 2013

несколько асинхронных вызовов могут быть переписаны с помощью Futures

var footask = QueryFooAsync();
var bartask = QueryBarAsync();
var baztask = QueryBazAsync();

var foos = await footask;
var bars = await bartask;
var baz = await baztask;

// do something with foos, bars, baz

может быть заменено на

var foos = session.Query<Foo>().....ToFuture();
var bars = session.Query<Bar>().....ToFuture();
var baz = session.Query<Bazes>().....ToFutureValue();

await Task.Factory.StartNew(() => var ignored = baz.Value)  // await the results

// do something with foos, bars, baz

, что даже имеет преимущество по сравнению с асинхронным кодом, так как вместо этого время возврата туда и обратно оплачивается только один раз3 раза.

12 голосов
/ 08 октября 2010

Обратите внимание, что асинхронные вызовы базы данных сами по себе НЕ подразумевают лучшей масштабируемости.Я рекомендую прочитать статью " Должны ли мои вызовы базы данных быть асинхронными? " для углубленного анализа.Вот цитата из этой статьи:

Один уважаемый архитектор БД / Веб зашел так далеко, что сказал:
Для приложений баз данных, использующих асинхронные операции для уменьшения количества заблокированных потоков на веб-серверепочти всегда полная трата времени.Небольшой веб-сервер может легко обрабатывать больше одновременных запросов на блокировку, чем серверная часть вашей базы данных может обрабатывать одновременно.Вместо этого убедитесь, что ваши сервисные вызовы дешевы в базе данных, и ограничьте количество одновременно выполняющихся запросов числом, которое вы протестировали для правильной работы и максимизации общей пропускной способности транзакции.

9 голосов
/ 21 марта 2010

К сожалению, нет. NHibernate не раскрывает внутреннюю реализацию выполнения команды так, как это делает L2S.

Вам потребуется использовать пул потоков ИЛИ создать патч для NH, чтобы добавить поддержку асинхронных запросов. Это будет приветствоваться сообществом и будет хорошим упражнением (но это совсем не тривиально)

1 голос
/ 23 июня 2018

Начиная с NHibernate v5, асинхронность теперь полностью поддерживается!

Вот несколько замечательных примеров:

Customer customer = await session.GetAsync<Customer>(1);

List<Customer> customers = await session.Query<Customer>().ToListAsync();

Customer customer = await session.Query<Customer>()
.Where(x => x.Name.Contains("Customer 1"))
.SingleOrDefaultAsync();

Обновление сущности

using (ISession session = sessionFactory.OpenSession())
using (ITransaction transaction = session.BeginTransaction())
{
    Customer customer = await session.GetAsync<Customer>(1);
    customer.Name = "Customer 3";
    await session.SaveOrUpdateAsync(customer);
    await transaction.CommitAsync();
}

Источник статьи

1 голос
/ 19 сентября 2012

Хотя в NH все еще не поддерживается асинхронные запросы, вы все же можете частично преодолеть некоторые нежелательные эффекты запуска (длительных) вызовов БД из потока запросов.

То, что вы хотите, это разделить Threadpool между короткими и долгосрочными операциями. Конечно, это невозможно с реальной реализацией Threadpool и TPL, но вы можете легко помочь себе, написав собственную очередь Producer / Consumer с ожидаемыми элементами и настраиваемой конкуренцией.

Пожалуйста, посмотрите на пример, который я собрал: https://gist.github.com/3746240

Код скопирован / вставлен из замечательной книги Джозефа Албахари и Бена Албахари "C # 5.0 в двух словах: исчерпывающий справочник", в которую я внес изменение, в результате которого планировщик создал выделенные рабочие потоки для обработки элементов.

...