多个异步 SqlClient 操作 - 寻找一个很好的例子
Posted
技术标签:
【中文标题】多个异步 SqlClient 操作 - 寻找一个很好的例子【英文标题】:Multiple Asynchronous SqlClient Operations - Looking for a good example 【发布时间】:2010-11-03 10:56:08 【问题描述】:我从一开始就在我的 WinForms 客户端中使用异步操作,但仅用于某些操作。当ExecuteReader
或ExecuteNonQuery
完成时,回调委托触发并且一切正常。
我基本上有两个问题:
1) 在现实生活系统中处理此问题的最佳结构是什么?我看到的所有示例都是玩具示例,其中表单处理操作完成,然后在EndExecuteReader
上打开数据读取器。当然,这意味着表单与数据库的耦合比您通常想要的更紧密。当然,表单总是可以很容易地调用.Invoke
。我已将所有异步对象设置为从 AsyncCtrlBlock<T>
类继承,并将表单和所有回调委托提供给 DAL 中异步对象的构造函数。
2) 我将重新访问当前不是异步的程序的一部分。它连续进行两次调用。当第一个完成时,可以填充模型的一部分。当第二部分完成时,模型的剩余部分可以完成 - 但前提是第一部分已经完成。构建这个的最佳方法是什么?如果可以完成第一次读取并且在启动第二次读取时正在进行由于第一次读取而导致的处理,那就太好了,但是我不希望在我知道处理第二次读取之前开始处理首次读取数据已完成。
【问题讨论】:
"如果可以完成第一次读取并且在启动第二次读取时正在进行由于第一次读取而导致的处理,那就太好了,但我不希望处理第二次读取开始,直到我知道第一次读取的数据的处理已经完成。” ----- 你的意思是第一个和第二个应该同时开始执行,但你不希望第二个在第一个完成之前完成? 在第一个完成事件的处理完成之前,我不会开始处理第二个完成事件。即第一个查询获得一组节点,第二个查询获得一组行。在实例化节点之前,我不能将线放在节点之间,然后我可以将它们与线关系查询的结果连接起来。 您的解释听起来 CTE、Common Table Expressions(请参阅 msdn.microsoft.com/en-us/library/ms190766.aspx)可以一步为您提供结果。在 WITH 内部定义第一个查询,并在 WITH 之后直接在 JOIN 语句的第二个查询中使用第一个查询的节点。不是这样吗? @Oleg 这两个集合可以通过连接合并为一个,但是速度较慢并且需要更多的客户端处理。关键是,一般来说,如果一个进程需要多个独立的结果集,但在处理中存在一些依赖性,你如何构建并行处理以及异步处理的一个很好的例子,它不只是让表单处理完成活动? 【参考方案1】:关于 2)
使模型填充的第一阶段异步。 你会有类似的东西
FisrtCall();
AsyncResult arPh1 = BeginPhaseOne(); //use results from first call
SecondCall();
EndPhaseOne(arPh1); //wait until phase one is finished
PhaseTwo(); //proceed to phase two
【讨论】:
为了获得赏金,我希望看到一个真实的示例代码,或者一个带有真实示例的文章的链接,其中 1) 不处理表单中的事件和 2 ) 显示如何对两个请求进行排队,但仅在第一个请求完成并已处理后才处理第二个请求(并且即使第二个请求仍处于挂起状态,也会处理第一个请求结果)【参考方案2】:如果您使用的是 .Net 4,这将是 TPL 的理想应用!你可以将你的代码分解成这样的任务:
TaskScheduler uiScheduler = GetUISheduller();
SqlCommand command1 = CreateCommand1();
Task<SqlDataReader> query1 = Task<SqlDataReader>.Factory.FromAsync(command1.BeginExecuteReader, command1.EndExecuteReader, null);
query1.ContinueWith(t => PopulateGrid1(t.Result), uiScheduler);
SqlCommand command2 = CreateCommand2();
query1.ContinueWith(t => Task<SqlDataReader>.Factory.FromAsync(command2.BeginExecuteReader, command2.EndExecuteReader, null)
.ContinueWith(t => PopulateGrid2(t.Result), uiScheduler);
【讨论】:
以上是关于多个异步 SqlClient 操作 - 寻找一个很好的例子的主要内容,如果未能解决你的问题,请参考以下文章