我编写了一个与MSSQL数据库交互的服务器。它目前用.NET 4.0编写,并使用NHibernate作为ORM从数据库中检索信息。在阅读有关.NET 4.5和async / await关键字的介绍时,我很快就了解到了NHibernate does not have support for async/await。
我不明白为什么向数据库发出异步调用会有所帮助。不是所有请求都在数据库级别排队吗?不同步只会增加失败点而不改进任何东西吗?
答案 0 :(得分:4)
通常,好处是您可以在运行可能昂贵的(异步)操作时阻止当前正在执行的线程。在WPF / Windows窗体应用程序的上下文中,这意味着您不会阻止UI线程(如果请求来自该线程)并且您的应用程序仍然响应。
在Web应用程序(例如IIS)的上下文中,这意味着您在等待结果时释放池中的线程。由于您没有锁定线程,因此可以重用它来接受另一个请求,并在接受的连接方面产生更好的性能(不一定是时间/请求)。
答案 1 :(得分:2)
请不要所有请求都在数据库级别排队?
没有。阅读Understanding how SQL Server executes a query。任何名副其实的数据库服务器都可以同时运行数百个请求。仅当请求是相关的(例如,您需要将查询1的输出作为参数传递给查询2)或在事务约束下操作时(在事务中任何时候只能激活一个语句),序列化才是必需的。 / p>
异步调用至少有两个主要优点:
资源使用情况。如果不考虑其他任何事情,只需将编程模型更改为事件驱动的异步模型,将导致应用程序可以驱动的吞吐量大幅增加。当然,这适用于后端应用程序(例如,Web服务器),而不适用于客户端用户驱动的应用程序,该应用程序将无法发送超出一个用户启动的内容。阅读High Performance Windows programs链接的文章。这也很重要,即使有点过时了:Asynchronous Pages in ASP.NET 2.0
重叠请求。同步模型doe snot允许向后端发出查询,直到当前完成。很多时候,应用程序有必要的信息(params)来发出两个或更多不相关的请求,但它只是可以。执行异步调用允许控制线程发出所有并行请求,并在完成后恢复。
.Net 4.5任务,NHibernate都不支持异步数据库编程。好老BeginExecuteXXX
实际上要强大得多,虽然有点晦涩难懂。
答案 2 :(得分:1)
NHibernate可以支持真正的异步调用。我已经在我自己的分支上实现了它
https://github.com/ReverseBlade/nhibernate-core/tree/nh_4.5.1
您可以查看并编译。它是针对.net 4.5.1编译的。它与标准的nhibernate兼容并通过所有测试。 然后你可以使用像.ToListAsync();或GetAsync(),它将进行真正的异步调用。
如果您需要帮助,可以撰写评论。祝你好运
答案 3 :(得分:1)
好消息。自v 5.0以来,NHibernate支持async / await开箱即用
答案 4 :(得分:0)
您可能会将语言功能与设计模式混淆; async
是帮助您管理后台任务的语法糖,而异步任务只是意味着您正在运行两个或更多线程。
仅仅因为NHibernate不支持async
并不意味着你不能异步运行。这对用户非常有利,因为您不想在对数据库/服务执行(相对)长时间运行的查询时冻结UI,尤其是在服务器陷入困境时。
我想你可以把这看作是一个失败点,但实际上只是一些方面:
Invoke
/ BeginInvoke
完成,不管您是在WinForms还是WPF中确定详细信息。编辑:
一些假设WPF和至少.NET 4.0的示例框架代码
Task.Factory.StartNew(() =>
{
using (var client = new dbClient())
{
// Perform query here
this.Dispatcher.BeginInvoke(new Action(() =>
{
// Set data source, etc, i.e.
this.Items = result;
}));
}
}).ContinueWith(ex => Logger.LogException(ex), TaskContinuationOptions.OnlyOnFaulted);
答案 5 :(得分:0)
你说:
请不要所有请求都在数据库级别排队?
如果通过“队列”你的意思是“单一服务队列”而不是答案是否定的。 SQL Server是一种高度异步和多线程的服务,可以同时为许多查询提供服务。
即使在物理层面,排队(即物理设备服务)也会同时分配在多个CPU核心上,以及组成磁盘阵列的物理磁盘数量。
因此,对SQL Server进行异步调用的原因是能够将一些多线程/多服务容量用于您自己的服务。