Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I run NHibenate queries asynchronously?

One way to increase scalability of the server application is to run IO-bound operation (reading files, sockets, web requests, database requests etc) asynchronously. This does not mean run them in the ThreadPool which will just block threads while operation is being executed. The correct way is to use asynchronous API (BeginRead, BeginGetResponse, BeginExecuteReader etc). The problem is well described in CLR vi C# book.

Here is some article about asynchronous queries in Linq to SQL.

Are any ways to execute Nhibernate query asynchonously? What about Linq to NHibernate?

Thank you, Andrey

like image 809
andrey.tsykunov Avatar asked Mar 21 '10 04:03

andrey.tsykunov


2 Answers

Note that async database calls do NOT imply better overall scalability by themselves. I recommend reading the article "Should my database calls be Asynchronous?" for an in-depth analysis. Here's a quote from that article:

One respected DB/Web architect went so far as to say:
For database applications using async operations to reduce the number of blocked threads on the web server is almost always a complete waste of time. A small web server can easily handle way more simultaneous blocking requests than your database back-end can process concurrently. Instead make sure your service calls are cheap at the database, and limit the number of concurrently executing requests to a number that you have tested to work correctly and maximize overall transaction throughput.

like image 53
Mauricio Scheffer Avatar answered Oct 09 '22 07:10

Mauricio Scheffer


multiple async calls can be rewritten with 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 

can be replaced with

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 

this even has the benefit over async code that the roundtrip time is only paid once instead of 3 times.

like image 43
Firo Avatar answered Oct 09 '22 09:10

Firo