我有一个本地数据库。
我有一个简单的类用于本地数据库的工作。
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
}
答案 0 :(得分:1)
我没有使用过数据库。也许您应该使用Dispatcher Invoke方法对您的数据库和UI执行某些操作,因为当您使用线程和UI工作时,必须使用Dispatcher。
谈论编写和读取数据库 - 它可以同时完成,但是如果仍在编写某些数据,并且您正在读取 - 则在写入完成之前数据将不会显示。
“一次只能让一个线程使用”
尝试使用锁并等待。但是你要做的是开发多线程程序,它不会比1个线程更快... = /
答案 1 :(得分:1)
如果您正在引用DataContext,那么它不是线程安全的,是的,您需要添加锁以使其保持一致。 InvalidOperationException可以通过使用UI线程(Deployment.Current.Dispatcher.BeginInvoke(()=&gt; {...}))来解决,只是为了干酪注意到db.SubmitChanges()方法。
另一种更常见的数据库解决方案是SQLite。不幸的是,我还没有使用多线程Windows Phone应用程序进行测试,因此我无法确定它是否适合您,即使它应该是一个线程安全的数据库。