2009-12-01 113 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