2011-10-22 30 views
3

我會有一個數據庫對象,可以從多個線程以及從主線程訪問。我不希望他們同時訪問底層的數據庫對象,所以我會編寫一系列可以從多個線程訪問的線程安全公共方法。可以使用Control.Invoke而不是使用鎖嗎?

我的第一個想法是圍繞我的連接使用lock,例如lock(oleDbConnection),但問題是我必須鎖定主線程,因爲它是一個可以訪問它的線程。這將意味着重寫大量的代碼。

但是,由於這些線程和主線程不會經常訪問數據庫,所以每次我從另一個線程調用任何數據庫方法時,只需使用我的控件的一些(可能是主窗體的)方法Invoke方法。這樣,據我所知,這些方法將永遠不會同時調用,我不需要擔心主線程。我想唯一的問題會降低性能一點點,但正如我所說,數據庫不經常訪問;我使用線程的原因並不是它們可以同時訪問數據庫,而是可以同時執行其他操作。

這聽起來像個好主意嗎?我錯過了什麼嗎?聽起來有點太容易,所以我很懷疑。

回答

4

這聽起來像它會工作AFAIK,但它也聽起來像一個真的壞主意

問題在於,在編寫lock時,您說「我希望此代碼成爲關鍵部分」,而編寫Invoke時您說「我希望在UI線程上執行該代碼」。這兩件事當然不是等同的,這可能會導致很多問題。例如:

  1. Invoke通常用於訪問UI控件。如果開發人員看到Invoke而沒有任何與UI相關的內容,那麼會發生什麼?「哎呀,這是不需要的Invoke;讓我們擺脫它吧」?
  2. 如果不止一個UI線程結束了,該怎麼辦?
  3. 如果數據庫操作需要很長時間(或超時)會怎麼樣?您的用戶界面將停止響應。
3

我會絕對去鎖。您通常希望UI線程在執行可能需要時間的操作時響應,其中包括任何類型的DB訪問;例如,你不知道它是否還活着。

此外,處理連接的典型方法是爲每個請求創建,使用和配置連接,而不是重複使用相同的連接。這可能可能解決一些併發問題。

1

你爲什麼不嘗試使用Connection Pool。每個線程都可以使用不同的數據庫連接完成其工作,並將結果發送到主線程InvokeConnection Pooling是服務器中常用的一種方法。

請參閱Using Connection Pooling with SQL Server

+0

如何在C#上使用連接池? – Juan

+1

您可以創建一個連接字符串,例如'Server = myAddress:myPortNumber; Database = myDataBase; UID = myUsername; PWD = myPassword; Max Pool Size = 100; Min Pool Size = 10;'然後在每個方法中創建並關閉連接。如果池中有可用的連接,您將從那裏獲得連接(在這種情況下不會創建新的連接,並且close將連接返回到池) –

相關問題