在Windows Phone 7/8中多线程和访问本地数据库

时间:2013-08-11 20:32:11

标签: c# database multithreading windows-phone-7 windows-phone-8

我有一个本地数据库。

我有一个简单的类用于本地数据库的工作。

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有来自不同线程的本地数据库的许多查询。但我只通过类DataBase使用本地数据库。我想避免出现删除或更新所选数据等情况。 所以,我想锁定数据库,使其一次只能用于一个线程。但我不希望它在性能方面成为应用程序的弱点。 如何最好地进行?什么最适合Windows Phone 7/8中的本地数据库?

更新

我找到了关于并发数据库访问的this post。也许我错了,但我认为这就是我的需要。

我重写了代码,现在我有类似的东西

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

 }

2 个答案:

答案 0 :(得分:1)

我没有使用过数据库。也许您应该使用Dispatcher Invoke方法对您的数据库和UI执行某些操作,因为当您使用线程和UI工作时,必须使用Dispatcher。

谈论编写和读取数据库 - 它可以同时完成,但是如果仍在编写某些数据,并且您正在读取 - 则在写入完成之前数据将不会显示。

“一次只能让一个线程使用”

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

答案 1 :(得分:1)

如果您正在引用DataContext,那么它不是线程安全的,是的,您需要添加锁以使其保持一致。 InvalidOperationException可以通过使用UI线程(Deployment.Current.Dispatcher.BeginInvoke(()=&gt; {...}))来解决,只是为了干酪注意到db.SubmitChanges()方法。

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