VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)實(shí)用技巧分享
大家通過(guò)對(duì)VB.NET編程語(yǔ)言的學(xué)習(xí)之后,可以知道,它在對(duì)數(shù)據(jù)庫(kù)方面的應(yīng)用時(shí)很靈活的。比如今天為大家介紹的VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)的相關(guān)方法,就可以一種靈活方便的方式來(lái)實(shí)現(xiàn)。#t#
線程是操作系統(tǒng)分配處理器時(shí)間的基本單元,線程可以在單個(gè)執(zhí)行線程執(zhí)行的同時(shí)運(yùn)行多個(gè)活動(dòng),支持搶先多任務(wù)處理的操作系統(tǒng)可以創(chuàng)建多個(gè)線程并通過(guò)時(shí)間片輪轉(zhuǎn)的方式使它們同時(shí)運(yùn)行。在需要良好用戶交互的應(yīng)用以及與網(wǎng)絡(luò)和數(shù)據(jù)庫(kù)進(jìn)行通訊的應(yīng)用中,使用多線程能提供良好的交互體驗(yàn),能對(duì)用戶的要求做出快速的反應(yīng)。本文主要介紹.NET中的線程在數(shù)據(jù)庫(kù)編程中的具體應(yīng)用(用VB.NET實(shí)現(xiàn))。
VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)1 創(chuàng)建數(shù)據(jù)庫(kù)訪問(wèn)線程
在數(shù)據(jù)庫(kù)應(yīng)用中,特別是網(wǎng)絡(luò)數(shù)據(jù)庫(kù)訪問(wèn),因?yàn)榭赡芤L問(wèn)的數(shù)據(jù)量較大,因此需要比較長(zhǎng)的時(shí)間來(lái)得到結(jié)果,而一個(gè)良好的程序應(yīng)具有良好的交互性,在訪問(wèn)數(shù)據(jù)庫(kù)時(shí)應(yīng)允許你的應(yīng)用程序?qū)τ脩舻幕顒?dòng)盡快做出響應(yīng),以提供豐富的用戶體驗(yàn)。利用多線程機(jī)制可以讓需要大量時(shí)間的操作在后臺(tái)運(yùn)行以快速響應(yīng)用戶的活動(dòng)。下面的代碼訪問(wèn)數(shù)據(jù)庫(kù)并返回?cái)?shù)據(jù)表:
- Private sub GetData
FromDataBase()- …
- m_table.Clear()
- m_sqlDataAdapter.
Fill(m_table)- …
- End Sub
創(chuàng)建Thread對(duì)象的新實(shí)例,需創(chuàng)建新的線程代理.ThreadStart線程代理可以指定生成線程時(shí)要執(zhí)行的方法名,但線程代理并不實(shí)際運(yùn)行線程.創(chuàng)建ThreadStart對(duì)象時(shí),需指定線程開(kāi)始執(zhí)行時(shí)要運(yùn)行的方法的指針,該方法不能接受任何參數(shù)。下面我們將上面的代碼分配給一個(gè)線程處理,并且啟動(dòng)它:
- Dim myThreadStart as ThreadStart
=New ThreadStart(AddressOf
GetDataFromDataBase)- Dim myThread as Thread=New
Thread(myThreadStart)- myThread.Start()
這樣當(dāng)進(jìn)行數(shù)據(jù)庫(kù)的訪問(wèn)時(shí),用戶可以繼續(xù)進(jìn)行處理。
VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)2 將數(shù)據(jù)庫(kù)訪問(wèn)方法封裝到類(lèi)
上面提到,線程要執(zhí)行的方法不能接受任何參數(shù),如果要傳入方法特定條件,可以將方法放在一個(gè)類(lèi)中,在類(lèi)中定義類(lèi)的屬性,需要時(shí)可以設(shè)置類(lèi)的屬性,然后用方法調(diào)用這些屬性以實(shí)現(xiàn)方法參數(shù)類(lèi)似的功能。同時(shí),因?yàn)樯傻木€程在主應(yīng)用程序線程之外運(yùn)行,.NET Framework提供線程隔離,這時(shí)如果要用新的線程操縱主應(yīng)用程序中的對(duì)象便不被允許。***的辦法也是將線程要訪問(wèn)的對(duì)象包裝在類(lèi)中。下面我們創(chuàng)建一個(gè)類(lèi),封裝屬性和數(shù)據(jù)庫(kù)訪問(wèn)方法:
- Public Class dealDataBase
- Private m_sqlDataAdapter As
SqlDataAdapter- Private m_table As DataTable
- Public Property setDataAdapter()
As SqlDataAdapter- Get
- setDataAdapter=m_sqlDataAdapter
- End Get
- Set(ByVal value As SqlDataAdapter)
- m_sqlDataAdapter=value
- End Set
- End Property
- Public Property setDataTable()
As DataTable- Get
- setDataTable=m_table
- End Get
- Set(ByVal value As DataTable)
- m_DataTable=value
- End Set
- End Property
- Public sub GetDataFromDataBase()
- …
- m_table.Clear()
- m_sqlDataAdapter.Fill(m_table)
- …
- End Sub
- End Class
下面是創(chuàng)建線程并運(yùn)行線程的代碼:
- Dim myDB As New dealDataBase ()
- Dim myThreadStart as ThreadStart
- Dim myThread as Thread
- myDB.setDataAdapter=Me.DataAdapter1
'DataAdapter1是本窗體內(nèi)定義的數(shù)據(jù)適配器- myDB.setDataTable=Me.DataTable1
'DataTable1是本窗體定義的數(shù)據(jù)表- …
- myThreadStart=New ThreadStart
(AddressOf myDB.GetDataFromDataBase)- myThread=New Thread(myThreadStart)
- myThread.Start()
- …
- End Sub
VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)3 使用事件
調(diào)用了線程的start方法,并不能確保其中的方法馬上執(zhí)行完,而要得到數(shù)據(jù)訪問(wèn)的結(jié)果又必須等其中的方法執(zhí)行完畢。如果在運(yùn)行線程后采用循環(huán)查詢的方法顯然影響了交互性,事件是從線程方法返回?cái)?shù)據(jù)的好方法。只要在線程方法所在的類(lèi)中定義一個(gè)事件,在線程方法中發(fā)出事件,而在窗體類(lèi)中生成代理。
首先在dealDataBase類(lèi)聲明后加進(jìn)事件:
- Public Class dealDataBase
- Public Event GetDataComplete
(ByVal e As DtatTable)- …
- End Class
- 在類(lèi)dealDataBase的GetDataFromDataBase()
方法中加入發(fā)出事件的代碼,放在
m_sqlDataAdapter.Fill(m_table)后:- Public sub GetDataFromDataBase()
- …
- m_sqlDataAdapter.Fill(m_table)
- RasiseEvent GetDataComplete(m_table)
- …
- End Sub
下面在窗體類(lèi)中生成代理
- Private Sub dealData
(ByVal e As DataTable)- '處理數(shù)據(jù)表
- End Sub
在創(chuàng)建線程并運(yùn)行線程的代碼中進(jìn)行事件連接,事件連接代碼放在運(yùn)行線程前, dealDataBase類(lèi)實(shí)例化后:
- AddHandler myDB.
GetDataComplete,AddressOf
dealData
這樣,當(dāng)線程方法執(zhí)行完畢就會(huì)發(fā)出事件,而dealData方法會(huì)響應(yīng)事件并做出處理。
VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)4 同步機(jī)制
當(dāng)多個(gè)線程需要共享相同的對(duì)象時(shí),因?yàn)槊總€(gè)線程都能改變對(duì)象的狀態(tài),因此會(huì)互相破壞對(duì)方的執(zhí)行。為防止多個(gè)線程同時(shí)訪問(wèn)共享對(duì)象就需要同步。.Net框架使用SyncLock…End SyncLock標(biāo)識(shí)限制線程訪問(wèn)的代碼段。 SyncLock可得到一個(gè)對(duì)象引用的唯一鎖,只要將該對(duì)象傳送給SyncLock.通過(guò)得到這個(gè)唯一鎖,你可以確保多個(gè)線程不會(huì)訪問(wèn)共享的數(shù)據(jù).比如要防止數(shù)據(jù)表DataTable1被多個(gè)進(jìn)程同時(shí)訪問(wèn),可以對(duì)要處理DataTable1的代碼做如下處理:
- SyncLock(DataTable1)
- '處理DataTable1數(shù)據(jù)表的代碼
- End SyncLock
5 總結(jié)
VB.NET線程訪問(wèn)數(shù)據(jù)庫(kù)的使用可以提高程序的效率和提供對(duì)用戶活動(dòng)的快速響應(yīng)。但線程的使用比較復(fù)雜,并有死鎖的可能,因此使用多線程一定要詳細(xì)考慮資源的要求和潛在的沖突。