0

我有一个本地数据库。

我有一个简单的类来处理本地数据库。

public class DataBase
{

    public void Select()
    {
        try
        {
            //something select from the DB
        }
        finally
        {

        }
    }

    public void Insert()
    {
        try
        {
            //something insert to the DB
        }
        finally
        {

        }
    }

    public void Update()
    {
        try
        {
            //something update in the DB
        }
        finally
        {

        }
    }


    public void Remove()
    {
        try
        {
            //something remove from the DB
        }
        finally
        {

        }
    }
}

A 从不同的线程对本地数据库进行许多查询。但我只通过一个类数据库使用本地数据库。我想避免选择的数据目前被删除或更新等情况。所以,我想锁定数据库,使其一次只能用于一个线程。但我不希望它成为应用程序在性能方面的弱点。如何最好地进行?什么最适合 Windows Phone 7/8 中的本地数据库?

更新

我发现这篇关于并发数据库访问的帖子。也许我错了,但我认为这就是我需要的。

我重写了代码,现在我有这样的东西

public class CacheDataContext : DataContext
    {    
      public static string DBConnectionString = "Data Source=isostore:/Cache.sdf";

      public CacheDataContext(string connectionString) : base(connectionString) { }

      public static AutoResetEvent OperationOnDatabaseUsers = new AutoResetEvent(true);

      public static AutoResetEvent OperationOnDatabaseCities = new AutoResetEvent(true);

     public static AutoResetEvent OperationOnDatabaseVenues = new AutoResetEvent(true);


     public Table<Users> UsersItems;

     public Table<Cities> CitiesItems;

     public Table<Venues> VenuesItems;    

    }

我在本地数据库中有三个表。我没有相关表格的重要时刻。

所以我继承了三个CacheDataContext,它实现了具体表的工作逻辑。每个上下文通过 AutoResetEvent 独立于其他上下文锁定。

  public class CacheDataContextUsers : CacheDataContext
 {
    public CacheDataContextUsers(string connectionString)  
        : base(connectionString) { }

    public void ClearUsers()
    {
             try
             {
                  OperationOnDatabaseUsers.WaitOne();
                   using (CacheDataContext context = new CacheDataContext(DBConnectionString))
                     {   
                        //remove all users from the local database
                        context.SubmitChanges();
                     }
             }
             finally
             {
                 OperationOnDatabaseUsers.Set();
             }
    }

    public void AddUser(User newUser)
    {
             try
             {
                  OperationOnDatabaseUsers.WaitOne();
                   using (CacheDataContext context = new CacheDataContext(DBConnectionString))
                     {   
                        //add user
                        context.SubmitChanges();
                     }
             }
             finally
             {
                 OperationOnDatabaseUsers.Set();
             }
    }

    //other operations

 }




 public class CacheDataContextVenues : CacheDataContext
 {
    public CacheDataContextVenues(string connectionString)  
        : base(connectionString) { }

    public void ClearVenues()
    {
             try
             {
                  OperationOnDatabaseVenues.WaitOne();
                   using (CacheDataContext context = new CacheDataContext(DBConnectionString))
                     {   
                        //remove all venues from the local database
                        context.SubmitChanges();
                     }
             }
             finally
             {
                 OperationOnDatabaseVenues.Set();
             }
    }

    public void AddVenue(Venue newVenue)
    {
             try
             {
                  OperationOnDatabaseVenues.WaitOne();
                   using (CacheDataContext context = new CacheDataContext(DBConnectionString))
                     {   
                        //add venue
                        context.SubmitChanges();
                     }
             }
             finally
             {
                 OperationOnDatabaseVenues.Set();
             }
    }

    //other operations

 }
4

2 回答 2

1

如果您指的是DataContext那么它不是线程安全的,是的,您需要添加锁以使其保持一致。InvalidOperationException 可以通过使用 UI 线程 (Deployment.Current.Dispatcher.BeginInvoke( ()=> {...} )) 来解决,正如 Cheese 所指出的,仅用于 db.SubmitChanges() 方法。

另一种更通用的数据库解决方案是SQLite。不幸的是,我还没有使用多线程 Windows Phone 应用程序对其进行测试,因此我无法确定它是否适合您,即使它应该是一个线程安全的数据库。

于 2013-08-12T17:29:52.927 回答
1

我没有使用过数据库。也许您应该使用 Dispatcher Invoke 方法来处理您的 DB 和 UI,因为当您使用线程和 UI 时,必须使用 Dispatcher。

谈论写入和读取数据库 - 它可以同时完成,但如果一些数据仍在写入,而您正在读取 - 数据在写入完成之前不会显示。

“一次只对一个线程可用”

尝试使用锁并等待。但是您要做的是开发不会比 1 线程更快的多线程程序... =/

于 2013-08-12T11:53:59.060 回答