2009-12-01 104 views
0

我有很多很少的小功能,每個都執行查詢。我只想要一次運行一個函數,線程同步的最佳方式是什麼,以避免SQLite(C#)中的數據庫鎖定問題。C#中的線程同步?

函數在多個類中,你將如何鎖定所有DB類中的所有函數,以便只有一個來自任何DB類的函數被執行。

回答

4

我會唱唱反調......爲什麼你是否想在單獨的線程中調用它們,如果一次只執行一個呢?我只是將工作項放入一個隊列中,並且每次只有一個線程從隊列中讀取一個隊列。

編輯: 根據我下面的評論,這裏是一個輔助類的例子,你可以用它來重構你的數據訪問到一個更集中的地方。這是一個非常基本的例子,沒有經過測試。

class Database { 
    private string connectionString; 
    private readonly object syncRoot = new object(); 

    public Database(string connectionString) { 
     this.connectionString = connectionString; 
    } 

    public void ExecuteReader(SqlCommand command, Action<IDataRecord> forEachRow) { 
     lock (syncRoot) { 
      using (var connection = new SqlConnection(connectionString)) { 
       command.Connection = connection; 
       connection.Open(); 

       using (var reader = command.ExecuteReader()) { 
        while (reader.Read()) { 
         forEachRow(reader); 
        } 
       } 
      } 
     } 
    } 
} 

var myDB = new Database("connection string"); 
var myCommand = new SqlCommand("select id from blah"); 
myDB.ExecuteReader(myCommand, row => Console.WriteLine("ID: {0}", row["id"])); 
+0

它不是故意的多線程,我得到數據庫鎖定問題。該線程可能是由於調用或任何其他事情。有很多地方使用數據庫,使用隊列進行同步將是一項艱鉅的工作。 – 2009-12-01 04:57:30

+0

您可能想要考慮將您的數據訪問重構爲輔助類,這將更容易防止此類重新進入。試圖協調跨多個類的鎖定會很快變得笨拙。我會在我的答案中提一個簡單的例子。 – Josh 2009-12-01 05:53:55

+0

對我來說看起來很酷,非常感謝,讓我試試這件事回到你身邊,如有任何問題。 – 2009-12-01 06:31:33

2

最簡單的方法是使用c#lock()關鍵字來創建一個通用對象並鎖定該對象。不過,我覺得這在管理大型項目時很麻煩,而且經常使用wait handles

我會得到一個連接到數據庫的函數,然後發送一個必須被調用來發信號通知等待句柄的函數。在獲得連接時,您可以嘗試等待拋出錯誤,而不是發生死鎖。

+0

函數是在多個類中的,你將如何鎖定所有DB類中的所有函數,以便只有一個來自任何DB類的函數被執行。 – 2009-12-01 04:48:41

+0

您正在鎖定的對象可能是全局靜態類,我猜想。 – bobber205 2009-12-01 04:50:22

2

要添加到重播的答案,你需要的代碼看起來像這樣:

public class MyClass 
{ 
    private readonly object lockObject = new object(); 

    public void MyMethod() 
    { 
     lock (lockObject) 
     { 
      // Do stuff 
     } 
    } 

    public void AnotherMethod() 
    { 
     lock (lockObject) 
     { 
      // Do stuff 
     } 
    } 
} 

喬恩斯基特擁有一支優秀的穿線系列:http://www.yoda.arachsys.com/csharp/threads/

+0

修改了這個問題。 – 2009-12-01 04:49:34

+0

@Bolia:我想我們需要更多的信息。對我來說,這聽起來像是一個糟糕的設計,讓單獨的類在數據庫上運行並試圖將它們全部分開。 – jasonh 2009-12-01 05:01:18