问题 有时候我们需要在SQL Server数据库上执行异步操作,即在后台任务中执行该操作,主程序则可以执行其它操作。
解决方案
使用SqlCommand类的BeginExecuteNonQuery、BeginExecuteReader或BeginExecuteXmlReader方法开始执行一个后台数据库操作。这些方法都会返回一个System.IAsyncResult对象,我们可以用它来获取操作的状态或使用同步线程等待该操作完成。使用IAsyncResult对象及SqlCommand相应的EndExecuteNonQuery、EndExecuteReader或EndExecuteXmlReader方法来获取操作的结果。
注意:只有SqlCommand类支持这里所将的异步操作,与其等价的Oracle、OleDb等Data Provider的Command类没有提供这种功能。
原理
通常我们都需要执行同步的数据库操作,即调用代码会一直等待这些操作完成。这是因为我们通常都会用到数据库操作的结果。但有些时候,异步数据库操作也很有用。
注意:要对一个SqlConnection连接执行异步操作,需要在其连接字符串中添加如下属性:Asynchronous Processing=true。
BeginExecuteNonQuery、BeginExecuteReader以及BeginExecuteXmlReader的参数可以跟其相应的同步操作方法ExecuteNonQuery、ExecuteReader、ExecuteXmlReader相同,同时它们还提供了重载方法接受两个额外的参数以支持异步操作:
- 一个System.AsyncCallBack类型的委托,操作完成后会调用委托指向的方法。如果该委托为null,那就要使用另一种机制来判断异步操作何时完成了;
- 一个object对象引用,运行时通过它与异步操作建立联系。异步操作不能访问这个对象,但我们的代码却可以在操作完成时访问它,这样就可以将异步操作与有用的状态信息联系在一起。
当心: 在异步操作执行过程中,必须确保我们使用的对象不能被不经意地释放掉。尤其要注意SqlConnection和SqlCommand对象。
示例代码 : 代码中使用的数据库是Northwind,演示了上述技术的基本用法。
class Program { public static void CallbackHandler(IAsyncResult result) { using (SqlCommand cmd = result.AsyncState as SqlCommand) { using (SqlDataReader reader = cmd.EndExecuteReader(result)) { lock (Console.Out) { Console.WriteLine( " Price of the The Most Expensive Products: " ); while (reader.Read()) { Console.WriteLine( " {0} = {1} " , reader[ " TenMostExpensiveProducts " ], reader[ " UnitPrice " ]); } } } } } static void Main( string [] args) { using (SqlConnection conn = new SqlConnection()) { conn.ConnectionString = @" server=(local);database=Northwind;uid=sa;Asynchronous Processing=true " ; SqlCommand cmd = conn.CreateCommand(); cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = " Ten Most Expensive Products " ; conn.Open(); cmd.BeginExecuteReader(CallbackHandler, cmd); for ( int count = 0 ; count < 10 ; count ++ ) { lock (Console.Out) { Console.WriteLine( " {0} : Continue processing " , DateTime.Now.ToString( " HH:mm:ss.ffff " )); } Thread.Sleep( 400 ); } } Console.WriteLine(); Console.ReadLine(); } } 参考: Visual C# 2005 Recipes A Problem-Solution Approach -- Allen Jones, Matthew MacDonald, Rakesh Rajan.
本文转自一个程序员的自省博客园博客,原文链接:http://www.cnblogs.com/anderslly/archive/2007/04/11/PerformAsynchronousDatabaseOperations.html,如需转载请自行联系原作者。