Подтвердить что ты не робот

Как запустить асинхронные запросы NHibenate?

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

Вот несколько статей о асинхронных запросах в Linq to SQL.

Являются ли какие-либо способы выполнения запроса Nhibernate асинхронно? Что относительно Linq для NHibernate?

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

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

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 раза.

Ответ 4

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

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

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

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