and*_*nov 20 .net nhibernate asynchronous linq-to-nhibernate
提高服务器应用程序可伸缩性的一种方法是异步运行IO绑定操作(读取文件,套接字,Web请求,数据库请求等).这并不意味着在ThreadPool中运行它们,它只会在执行操作时阻塞线程.正确的方法是使用异步API(BeginRead,BeginGetResponse,BeginExecuteReader等).这个问题在CLR vi C# book中有详细描述.
这是一篇关于Linq to SQL中的异步查询的文章.
是否有任何方法可以异步执行Nhibernate查询?怎么样Linq到NHibernate?
谢谢,安德烈
Mau*_*fer 12
请注意,异步数据库调用本身并不意味着更好的整体可伸缩性.我建议阅读文章" 我的数据库应该调用异步吗? "进行深入分析.以下是该文章的引用:
一位受人尊敬的DB/Web架构师甚至说:
对于使用异步操作来减少Web服务器上被阻塞线程数的数据库应用程序几乎总是浪费时间.小型Web服务器可以轻松处理比数据库后端可以同时处理的更多同时阻塞请求的方式.相反,请确保您的服务调用在数据库中很便宜,并将并发执行的请求数限制为您已测试的数字以正常工作并最大化整体事务吞吐量.
Fir*_*iro 12
可以使用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
Run Code Online (Sandbox Code Playgroud)
可以替换为
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
Run Code Online (Sandbox Code Playgroud)
这甚至比异步代码更有利于往返时间只支付一次而不是3次.
很不幸的是,不行.NHibernate不会像L2S那样公开命令执行的内部实现.
您必须使用线程池或为NH创建补丁以添加异步查询支持.这将是社区非常欢迎的,并且可以进行一次很好的锻炼(但这根本不是微不足道的)
从 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();
Run Code Online (Sandbox Code Playgroud)
更新实体
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();
}
Run Code Online (Sandbox Code Playgroud)