2010-08-04 53 views
1

我是線程的新手,試圖在我去的時候學習它。請不要做任何假設,並嘗試解釋看似明顯的線程概念和規則。VB跨線程共享(靜態)成員訪問

我有一個模塊(靜態類),如下所示:

模塊主要

Private ReadOnly _dbConn As SqlClient.SqlConnection 

Public ReadOnly Property DBConn() As SqlClient.SqlConnection 
    Get 
     Debug.Print("Accessing DBConn") 
     Return _dbConn 
    End Get 
End Property 

Sub New() 
    _dbConn = New SqlClient.SqlConnection(My.Resources.ConnectionString) 
End Sub 

前端模塊

所有整個應用程序,當我在同一個線程訪問DBConn,它的工作原理如預期。然而,後來我創建了一個試圖訪問DBConn的後臺工作,並且什麼也沒有發生,線程只是掛起(後臺工作者)。我沒有得到打印輸出,應用程序不能繼續。後臺工作線程不會繼續超過這一點,因此線程永遠不會退出。我沒有得到任何異常,並且我無法在Visual Studio中進行調試(Visual Studio掛起)。 我想這是一個2部分的問題:爲什麼我不能從另一個線程訪問DBConn,爲什麼它沒有給我一個threadAccess異常而掛起?此外,爲什麼視覺工作室掛起(我假設它掛起,因爲線程掛起)?

請注意:我不是在問練習。我知道我不應該共享相同的連接,而是返回一個新的連接。在這個特定的應用程序中,它是安全的,因爲(儘管我在後臺線程上執行它)按照應用程序的流程,連接一次只能訪問一個。我只想知道爲什麼它掛在整個線程。

回答

0

這應該是一個類而不是模塊。然後,您可以使用引用將連接傳遞給相應的線程。

例如:

Private myConn as New NameofDataConnectionClass 
Private myWorkerClass as New NameofProcessClass 
myWorkerClass.DataConnection = myConn 
Private thd as New Threading.Thread(AddressOf myWorkerClass.Method) 
thd.Start()

顯然,這在邏輯上被編碼沒有特別。重點是實例化你的連接類,然後將它傳遞給由線程或後臺工作人員處理的合適的類。

+0

模塊是一個實例化的類。在VB中,當在模塊中編寫構造函數時,它是一個靜態構造函數,只要對模塊中的任何成員進行任何引用,就會獲得初始化。在我調用連接的時候,它已經被靜態構造函數實例化了。這是由連接成員在被另一個線程調用之前被訪問的事實所支持的。我沒有收到NullRefererenceException。請詳細解釋問題是什麼以及您的解決方案是什麼。 – Fragilerus 2010-08-04 17:34:08

+0

當您使用交叉線程時,您需要傳遞對象的引用,因爲實例化的模塊不會傳遞給新線程。它仍然在你的應用程序的當前線程中。這就是爲什麼您需要將對象引用傳遞給包裝數據連接的類的新線程。 – Josaph 2010-08-04 17:47:58

+0

我不認爲這是正確的。線程共享堆內存空間。因此另一個線程應該能夠訪問模塊的同一個實例。我測試這一點,它預製如預期 私人小組溫度() 昏暗BG作爲新System.ComponentModel.BackgroundWorker 的AddHandler bg.DoWork,AddressOf更改 bg.RunWorkerAsync() Threading.Thread.Sleep(TimeSpan.FromSeconds(3- )) Console.WriteLine(Module1.Member) End Sub Public Sub(ByVal sender As Object,ByVal e As DoWorkEventArgs) Module1.Member =「Changed」 End Sub – Fragilerus 2010-08-04 18:34:40