我有很多很少的小功能,每個都執行查詢。我只想要一次運行一個函數,線程同步的最佳方式是什麼,以避免SQLite(C#)中的數據庫鎖定問題。C#中的線程同步?
函數在多個類中,你將如何鎖定所有DB類中的所有函數,以便只有一個來自任何DB類的函數被執行。
我有很多很少的小功能,每個都執行查詢。我只想要一次運行一個函數,線程同步的最佳方式是什麼,以避免SQLite(C#)中的數據庫鎖定問題。C#中的線程同步?
函數在多個類中,你將如何鎖定所有DB類中的所有函數,以便只有一個來自任何DB類的函數被執行。
我會唱唱反調......爲什麼你是否想在單獨的線程中調用它們,如果一次只執行一個呢?我只是將工作項放入一個隊列中,並且每次只有一個線程從隊列中讀取一個隊列。
編輯: 根據我下面的評論,這裏是一個輔助類的例子,你可以用它來重構你的數據訪問到一個更集中的地方。這是一個非常基本的例子,沒有經過測試。
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"]));
最簡單的方法是使用c#lock()關鍵字來創建一個通用對象並鎖定該對象。不過,我覺得這在管理大型項目時很麻煩,而且經常使用wait handles。
我會得到一個連接到數據庫的函數,然後發送一個必須被調用來發信號通知等待句柄的函數。在獲得連接時,您可以嘗試等待拋出錯誤,而不是發生死鎖。
函數是在多個類中的,你將如何鎖定所有DB類中的所有函數,以便只有一個來自任何DB類的函數被執行。 – 2009-12-01 04:48:41
您正在鎖定的對象可能是全局靜態類,我猜想。 – bobber205 2009-12-01 04:50:22
要添加到重播的答案,你需要的代碼看起來像這樣:
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/
修改了這個問題。 – 2009-12-01 04:49:34
@Bolia:我想我們需要更多的信息。對我來說,這聽起來像是一個糟糕的設計,讓單獨的類在數據庫上運行並試圖將它們全部分開。 – jasonh 2009-12-01 05:01:18
它不是故意的多線程,我得到數據庫鎖定問題。該線程可能是由於調用或任何其他事情。有很多地方使用數據庫,使用隊列進行同步將是一項艱鉅的工作。 – 2009-12-01 04:57:30
您可能想要考慮將您的數據訪問重構爲輔助類,這將更容易防止此類重新進入。試圖協調跨多個類的鎖定會很快變得笨拙。我會在我的答案中提一個簡單的例子。 – Josh 2009-12-01 05:53:55
對我來說看起來很酷,非常感謝,讓我試試這件事回到你身邊,如有任何問題。 – 2009-12-01 06:31:33