SQL Server与.NET异步处理中的异步处理

时间:2009-11-14 02:28:28

标签: .net sql-server asynchronous

在SQL Server中使用异步处理而不是.NET异步处理有什么优势?他们不一样吗?我很难理解在SQL Server中使用异步处理而不是.NET APM的好处是什么。我可以轻松地将一个SQL调用包装在一个lambda表达式中并执行一个BeginInvoke(...)。

有人可以帮助我解决两者的不同和好处吗?

5 个答案:

答案 0 :(得分:9)

.NET异步处理(BeginInvoke(...))的问题在于,所有这一切都是分离线程以同步处理代码。 5分钟的查询将占用一个线程5分钟,阻塞(即在99%的时间内不做任何事情),同时在远程端计算结果。在压力下(一次多次查询),这将耗尽线程池,将所有线程捆绑在阻塞状态。线程池将变得无响应,并且新的工作请求将遭受等待线程池启动额外线程的大延迟。这不是线程池的预期用途,因为它的设计期望它要求完成的任务是短暂的和非阻塞的。

使用Begin / EndAction APM对,可以以非阻塞方式调用相同的操作,并且只有当结果通过IO完成端口返回时才会将其排队为线程池中的工作项。在过渡期间,你的所有线程都没有被束缚,并且在处理排队响应时,数据可用意味着用户代码不会阻塞IO,并且可以快速完成...更有效地使用threadpool,它可以扩展到更多客户端请求,而不需要每次未完成操作的线程成本。

答案 1 :(得分:5)

如前面的答案所述,BeginInvoke使用.NET线程。同样重要的是,该线程来自ASP.NET线程池,因此它与客户竞争非常有限的线程资源。 ThreadPool.QueueUserWorkItem()也是如此。

SqlClient异步调用需要启用了async = true的SqlConnection。该模式需要更多的网络开销(这是默认情况下未启用的原因),但它不会消耗.NET线程池中的线程。相反,它使用异步I / O.

后一种方法的优点是它的可扩展性更高。您可以通过这种方式处理数百或数千个并发请求,其中每次调用线程的开销将是极端的。另外,您将非常快速地使用整个ASP.NET线程池(默认情况下它最多只有12个线程)。

答案 2 :(得分:3)

.Net BeginInvoke只是将执行推迟到另一个线程。这将始终比同步调用慢,并消耗额外的资源。使用它的唯一原因是释放调用者上下文以继续进行其他操作(例如,将HTTP请求的结果返回给客户端)。

当连接上的AsynchronousProcessing属性设置为true并且使用SqlCommand的BeginExecute方法时,SqlClient异步方法是真正异步的。 SQL命令将发布到网络通信通道,并在服务器返回结果时调用完成。

从可靠性的角度来看,虽然这两种方法都没有用。他们都依赖客户端进程来保持呼叫,直到呼叫完成,否则SQL Server将看到客户端断开连接并放弃处理,回滚任何中间工作。考虑接受HTTP请求的ASP应用程序,提交“异步”支付处理并返回响应。没有任何方法可以保证提交的作品真正发生。

对于处理需要可靠性的情况,保证解决方案在服务器上排队工作,提交然后继续,依赖SQL Server自己的异步处理功能。这是一种方法,即使存在客户端断开连接,ASP进程“回收”,SQL Server镜像或群集故障转移,硬件灾难恢复,几乎任何可以抛出的东西,都可以保证处理,因为这是一种事务性持久的提交方式异步处理请求。有关示例,请参阅Asynchronous Procedure Execution

答案 3 :(得分:0)

从这篇文章SQL Server 2008 Books Online (October 2009) - Performing Asynchronous Operations,我引用:

  

异步处理启用   没有的方法立即返回   阻塞调用线程。这个   允许大部分的力量和   多线程的灵活性,没有   要求开发人员明确   创建线程或句柄   同步。

如果您已经明确创建了这些线程并处理了同步,那么您可能找不到太多差异。

答案 4 :(得分:0)

如果您的意思是“为什么使用数据提供者BeginExecute___()/EndExecute____()方法而不是在委托中包装普通Execute____(),我怀疑答案是他们第一次为ado.net设计提供者模型时对于.Net 1.0,在委托中包装内容并异步调用它并不是那么简单。

其他可能的原因是,这与原始.Net的旧代码更新或包装的工作方式相匹配,或者内置方法允许您轻松检查任何返回的异常

相关问题