How can I run NHibenate queries asynchronously?

后端 未结 5 764
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-30 23:15

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 doe

相关标签:
5条回答
  • 2020-12-30 23:51

    Unfortunately, no. NHibernate does not expose the internal implementation of the command execution in the way L2S does.

    You'll have to use the threadpool OR create a patch for NH to add asynchronous query support. That would be very welcome by the community and would make for a nice exercise (but it's not trivial at all)

    0 讨论(0)
  • 2020-12-30 23:52

    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.

    0 讨论(0)
  • 2020-12-30 23:55

    Although there is still no support for async queries in NH, you can still partially overcome some of the undesired effects of running (long-running) db calls from request thread.

    What you want is to split Threadpool between short-running and long-running operations. Of course this is not possible with actual implementation of Threadpool and TPL but you can help yourself quite eassilly by writing your own Producer/Consumer queue with awaitable items and customized concurency.

    Please have a look at example i have put together : https://gist.github.com/3746240

    Code is copy/pasted from great book "C# 5.0 in a Nutshell: The Definitive Reference" by Joseph Albahari and Ben Albahari with modification done by me causing the scheduler to create dedicated worker threads for items proccesing.

    0 讨论(0)
  • 2020-12-31 00:00

    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.

    0 讨论(0)
  • 2020-12-31 00:07

    As of NHibernate v5, async is now fully supported!

    Here are some nifty examples:

    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();
    

    Updating an entity

    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();
    }
    

    Source article

    0 讨论(0)
提交回复
热议问题