简体   繁体   English

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

[英]Multithreading and access to a local database in Windows Phone 7/8

I have a local database. 我有一个本地数据库。

And I have simple class for works with the local database. 我有一个简单的类用于本地数据库的工作。

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 have many queries to local database from a different threads. A有来自不同线程的本地数据库的许多查询。 But I work with local database only through a class DataBase. 但我只通过类DataBase使用本地数据库。 I want to avoid a situation where the selected data, which at the moment are deleted or updated, etc. So, I want to lock the database, making it available to only one thread at a time. 我想避免所选数据的情况,此时此类数据被删除或更新等等。因此,我想锁定数据库,使其一次只能用于一个线程。 But I do not want it to be a weak point of the app in terms of performance. 但我不希望它在性能方面成为应用程序的弱点。 How best to proceed? 如何最好地进行? What best suits to the local database in Windows Phone 7/8? 什么最适合Windows Phone 7/8中的本地数据库?

Update 更新

I found this post about concurrent database access. 我发现这篇关于并发数据库访问的帖子 Maybe I'm wrong, but I think that's what I need. 也许我错了,但我认为这就是我的需要。

I rewrote the code, now I have something like this 我重写了代码,现在我有类似的东西

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;    

    }

I have three tables in the local database. 我在本地数据库中有三个表。 Important moment that I don't have related tables. 我没有相关表格的重要时刻。

So I have three inherited from the CacheDataContext , which implements logic of work with concrete table. 所以我有三个继承自CacheDataContext ,它实现了具体表的工作逻辑。 Each context locked independently of the other contexts through AutoResetEvent. 每个上下文通过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

 }

I haven't worked with databases. 我没有使用过数据库。 Maybe you should use Dispatcher Invoke method to do something with your DB and UI, because when you work wih threads and UI it's necessary to use Dispatcher. 也许您应该使用Dispatcher Invoke方法对您的数据库和UI执行某些操作,因为当您使用线程和UI工作时,必须使用Dispatcher。

And talking about writing and reading the database - it can be done at same time, but if some data is still being written, and you are doing read - the data won't show up till writting is done. 谈论编写和读取数据库 - 它可以同时完成,但如果仍在编写某些数据,并且您正在读取 - 则在写入完成之前数据将不会显示。

"making it available to only one thread at a time" “一次只能为一个线程提供”

Try using locks and await. 尝试使用锁并等待。 But what you are trying to do - is to develop multi-thread program that won't work faster then 1 thread... =/ 但是你要做的是 - 开发多线程程序,它不会比1个线程更快... = /

If you are refering to DataContext then its not thread safe and yes you need to add locks in order for it to be consistent. 如果您正在引用DataContext,那么它不是线程安全的,是的,您需要添加锁以使其保持一致。 InvalidOperationException could be solved by using the UI thread (Deployment.Current.Dispatcher.BeginInvoke( ()=> {...} )) just for the db.SubmitChanges() method as Cheese noted. InvalidOperationException可以通过使用UI线程(Deployment.Current.Dispatcher.BeginInvoke(()=> {...}))来解决,只是针对db.SubmitChanges()方法,如Cheese所述。

Another DB solution, more general, would be SQLite . 更常见的另一个数据库解决方案是SQLite Unfortunately I have not tested it with a multi-threaded Windows Phone application yet and thus I cannot tell you for sure if it will suit you or not, even though it is supposed to be a thread safe database. 不幸的是我还没有使用多线程Windows Phone应用程序进行测试,因此我无法确定它是否适合您,即使它应该是一个线程安全的数据库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM