细说多线程(六) —— 异步 SqlCommand
目錄
一、線程的定義
二、線程的基礎知識
三、以ThreadStart方式實現多線程
四、CLR線程池的工作者線程
五、CLR線程池的I/O線程
六、異步 SqlCommand
七、并行編程與PLINQ
八、計時器與鎖
?
六、異步 SqlCommand
從ADO.NET 2.0開始,SqlCommand就新增了幾個異步方法執行SQL命令。相對于同步執行方式,它使主線程不需要等待數據庫的返回結果,在使用復雜性查詢或 批量插入時將有效提高主線程的效率。使用異步SqlCommand的時候,請注意把ConnectionString 的?Asynchronous Processing 設置為 true 。
注意:SqlCommand異步操作的特別之處在于線程并不依賴于CLR線程池,而是由Windows內部提供,這比使用異步委托更有效率。但如果需要使用回調函數的時候,回調函數的線程依然是來自于CLR線程池的工作者線程。
SqlCommand有以下幾個方法支持異步操作:
public IAsyncResult BeginExecuteNonQuery (......)
public int EndExecuteNonQuery(IAsyncResult)
public IAsyncResult BeginExecuteReader(......)
public SqlDataReader EndExecuteReader(IAsyncResult)
public IAsyncResult BeginExecuteXmlReader (......)
public XmlReader EndExecuteXmlReader(IAsyncResult)
?
由于使用方式相似,此處就以 BeginExecuteNonQuery 為例子,介紹一下異步SqlCommand的使用。首先建立connectionString,注意把Asynchronous Processing設置為true來啟動異步命令,然后把SqlCommand.CommandText設置為 WAITFOR DELAY "0:0:3" 來虛擬數據庫操作。再通過BeginExecuteNonQuery啟動異步操作,利用輪詢方式監測操作情況。最后在操作完成后使用 EndExecuteNonQuery完成異步操作。
1 class Program 2 { 3 //把Asynchronous Processing設置為true4 static string connectionString = "Data Source=LESLIE-PC;Initial Catalog=Business;“+
5 "Integrated Security=True;Asynchronous Processing=true"; 6 7 static void Main(string[] args) 8 { 9 //把CLR線程池最大線程數設置為1000
10 ThreadPool.SetMaxThreads(1000, 1000); 11 ThreadPoolMessage("Start"); 12 13 //使用WAITFOR DELAY命令來虛擬操作
14 SqlConnection connection = new SqlConnection(connectionString); 15 SqlCommand command = new SqlCommand("WAITFOR DELAY '0:0:3';", connection); 16 connection.Open(); 17 18 //啟動異步SqlCommand操作,利用輪詢方式監測操作
19 IAsyncResult result = command.BeginExecuteNonQuery(); 20 ThreadPoolMessage("BeginRead"); 21 while (!result.AsyncWaitHandle.WaitOne(500)) 22 Console.WriteLine("Main thread do work........"); 23 24 //結束異步SqlCommand
25 int count= command.EndExecuteNonQuery(result); 26 ThreadPoolMessage("\nCompleted"); 27 Console.ReadKey(); 28 } 29 30 //顯示線程池現狀
31 static void ThreadPoolMessage(string data) 32 { 33 int a, b; 34 ThreadPool.GetAvailableThreads(out a, out b); 35 string message = string.Format("{0}\n CurrentThreadId is {1}\n "+ 36 "WorkerThreads is:{2} CompletionPortThreads is :{3}\n", 37 data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString()); 38 Console.WriteLine(message); 39 } 40 }
注意運行結果,SqlCommand的異步執行線程并不屬于CLR線程池。
?
如果覺得使用輪詢方式過于麻煩,可以使用回調函數,但要注意當調用回調函數時,線程是來自于CLR線程池的工作者線程。
class Program{//把Asynchronous Processing設置為truestatic string connectionString = "Data Source=LESLIE-PC;Initial Catalog=Business;”+“Integrated Security=True;Asynchronous Processing=true";static void Main(string[] args){//把CLR線程池最大線程數設置為1000
ThreadPool.SetMaxThreads(1000, 1000);ThreadPoolMessage("Start");//使用WAITFOR DELAY命令來虛擬操作
SqlConnection connection = new SqlConnection(connectionString);SqlCommand command = new SqlCommand("WAITFOR DELAY '0:0:3';", connection);connection.Open();//啟動異步SqlCommand操作,并把SqlCommand對象傳遞到回調函數
IAsyncResult result = command.BeginExecuteNonQuery(new AsyncCallback(AsyncCallbackMethod),command);Console.ReadKey();}static void AsyncCallbackMethod(IAsyncResult result){Thread.Sleep(200);ThreadPoolMessage("AsyncCallback");SqlCommand command = (SqlCommand)result.AsyncState;int count=command.EndExecuteNonQuery(result);command.Connection.Close();}//顯示線程池現狀
static void ThreadPoolMessage(string data){int a, b;ThreadPool.GetAvailableThreads(out a, out b);string message = string.Format("{0}\n CurrentThreadId is {1}\n "+"WorkerThreads is:{2} CompletionPortThreads is :{3}\n",data, Thread.CurrentThread.ManagedThreadId, a.ToString(), b.ToString());Console.WriteLine(message);}}
運行結果:
?對JAVA與.NET開發有興趣的朋友歡迎加入QQ群:162338858?
?
本文轉自 leslies2 ?51CTO博客,原文鏈接:http://blog.51cto.com/79100812/835861總結
以上是生活随笔為你收集整理的细说多线程(六) —— 异步 SqlCommand的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 巡检,不再要你磨破机房门槛
- 下一篇: 二叉树面试题